Skip to content

Commit 2f5b633

Browse files
Add comments explaining some of the changes to array.js.
1 parent c4a9149 commit 2f5b633

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

src/prototype/lang/array.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@ Array.from = $A;
447447
}
448448

449449
// 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.
450453
function concat(_) {
451454
var array = [], items = slice.call(arguments, 0), item, n = 0;
452455
items.unshift(this);
@@ -465,15 +468,33 @@ Array.from = $A;
465468
return array;
466469
}
467470

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.
468485
function wrapNative(method) {
469486
return function() {
470487
if (arguments.length === 0) {
488+
// No iterator was given. Instead of throwing a `TypeError`, use
489+
// `Prototype.K` as the default iterator.
471490
return method.call(this, Prototype.K);
472491
} else if (arguments[0] === undefined) {
492+
// Same as above.
473493
var args = slice.call(arguments, 1);
474-
args.unshift(Prototype.K)
494+
args.unshift(Prototype.K);
475495
return method.apply(this, args);
476496
} else {
497+
// Pass straight through to the native method.
477498
return method.apply(this, arguments);
478499
}
479500
};
@@ -487,7 +508,7 @@ Array.from = $A;
487508
var results = [], context = arguments[1], n = 0;
488509

489510
for (var i = 0, length = this.length; i < length; i++) {
490-
if (i in this) {
511+
if (i in this)
491512
results[n] = iterator.call(context, this[i], i, this);
492513
}
493514
n++;
@@ -498,10 +519,13 @@ Array.from = $A;
498519
}
499520

500521
if (arrayProto.filter) {
522+
// `Array#filter` requires an iterator by nature, so we don't need to
523+
// wrap it.
501524
var filter = Array.prototype.filter;
502525
} else {
503526
function filter(iterator) {
504-
if (!Object.isFunction(iterator)) { throw new TypeError(); }
527+
if (!Object.isFunction(iterator))
528+
throw new TypeError();
505529
var results = [], context = arguments[1], value;
506530

507531
for (var i = 0, length = this.length; i < length; i++) {
@@ -550,14 +574,14 @@ Array.from = $A;
550574
}
551575
}
552576

577+
// Prototype's `Array#inject` behaves identically to ES5's `Array#reduce`.
553578
if (arrayProto.reduce) {
554-
// Keep a copy of the native reduce
555579
var _reduce = arrayProto.reduce;
556580
function inject(memo, iterator) {
557581
iterator = iterator || Prototype.K;
558582
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.
561585
return _reduce.call(this, iterator.bind(context), memo, context);
562586
}
563587
} else {
@@ -605,7 +629,7 @@ Array.from = $A;
605629

606630
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
607631

608-
// use native browser JS 1.6 implementation if available
632+
// Use native browser JS 1.6 implementations if available.
609633
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
610634
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
611635
})();

0 commit comments

Comments
 (0)