@@ -447,6 +447,9 @@ Array.from = $A;
447
447
}
448
448
449
449
// Replaces a built-in function. No PDoc needed.
450
+ //
451
+ // Used instead of the broken version of Array#concat in some versions of
452
+ // Opera. Made to be ES5-compliant.
450
453
function concat ( _ ) {
451
454
var array = [ ] , items = slice . call ( arguments , 0 ) , item , n = 0 ;
452
455
items . unshift ( this ) ;
@@ -465,15 +468,33 @@ Array.from = $A;
465
468
return array ;
466
469
}
467
470
471
+ // Certain ES5 array methods have the same names as Prototype array methods
472
+ // and perform the same functions.
473
+ //
474
+ // Prototype's implementations of these methods differ from the ES5 spec in
475
+ // the way a missing iterator function is handled. Prototype uses
476
+ // `Prototype.K` as a default iterator, while ES5 specifies that a
477
+ // `TypeError` must be thrown. Implementing the ES5 spec completely would
478
+ // break backward compatibility and would force users to pass `Prototype.K`
479
+ // manually.
480
+ //
481
+ // Instead, if native versions of these methods exist, we wrap the existing
482
+ // methods with our own behavior. This has very little performance impact.
483
+ // It violates the spec by suppressing `TypeError`s for certain methods,
484
+ // but that's an acceptable trade-off.
468
485
function wrapNative ( method ) {
469
486
return function ( ) {
470
487
if ( arguments . length === 0 ) {
488
+ // No iterator was given. Instead of throwing a `TypeError`, use
489
+ // `Prototype.K` as the default iterator.
471
490
return method . call ( this , Prototype . K ) ;
472
491
} else if ( arguments [ 0 ] === undefined ) {
492
+ // Same as above.
473
493
var args = slice . call ( arguments , 1 ) ;
474
- args . unshift ( Prototype . K )
494
+ args . unshift ( Prototype . K ) ;
475
495
return method . apply ( this , args ) ;
476
496
} else {
497
+ // Pass straight through to the native method.
477
498
return method . apply ( this , arguments ) ;
478
499
}
479
500
} ;
@@ -487,7 +508,7 @@ Array.from = $A;
487
508
var results = [ ] , context = arguments [ 1 ] , n = 0 ;
488
509
489
510
for ( var i = 0 , length = this . length ; i < length ; i ++ ) {
490
- if ( i in this ) {
511
+ if ( i in this )
491
512
results [ n ] = iterator . call ( context , this [ i ] , i , this ) ;
492
513
}
493
514
n ++ ;
@@ -498,10 +519,13 @@ Array.from = $A;
498
519
}
499
520
500
521
if ( arrayProto . filter ) {
522
+ // `Array#filter` requires an iterator by nature, so we don't need to
523
+ // wrap it.
501
524
var filter = Array . prototype . filter ;
502
525
} else {
503
526
function filter ( iterator ) {
504
- if ( ! Object . isFunction ( iterator ) ) { throw new TypeError ( ) ; }
527
+ if ( ! Object . isFunction ( iterator ) )
528
+ throw new TypeError ( ) ;
505
529
var results = [ ] , context = arguments [ 1 ] , value ;
506
530
507
531
for ( var i = 0 , length = this . length ; i < length ; i ++ ) {
@@ -550,14 +574,14 @@ Array.from = $A;
550
574
}
551
575
}
552
576
577
+ // Prototype's `Array#inject` behaves identically to ES5's `Array#reduce`.
553
578
if ( arrayProto . reduce ) {
554
- // Keep a copy of the native reduce
555
579
var _reduce = arrayProto . reduce ;
556
580
function inject ( memo , iterator ) {
557
581
iterator = iterator || Prototype . K ;
558
582
var context = arguments [ 2 ] ;
559
- // The iterator has to be bound, as Array.prototype. reduce
560
- // always executes the iterator in the global context.
583
+ // The iterator must be bound, as ` Array# reduce` always executes the
584
+ // iterator in the global context.
561
585
return _reduce . call ( this , iterator . bind ( context ) , memo , context ) ;
562
586
}
563
587
} else {
@@ -605,7 +629,7 @@ Array.from = $A;
605
629
606
630
if ( CONCAT_ARGUMENTS_BUGGY ) arrayProto . concat = concat ;
607
631
608
- // use native browser JS 1.6 implementation if available
632
+ // Use native browser JS 1.6 implementations if available.
609
633
if ( ! arrayProto . indexOf ) arrayProto . indexOf = indexOf ;
610
634
if ( ! arrayProto . lastIndexOf ) arrayProto . lastIndexOf = lastIndexOf ;
611
635
} ) ( ) ;
0 commit comments