mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-09 02:17:50 +00:00
Avoid _.isArray returning true for arguments objects in browsers that report arguments.constructor as Array.
Former-commit-id: 9fccc5219e7cb6a007138f1f474d9e68504a0260
This commit is contained in:
49
build.js
49
build.js
@@ -174,7 +174,7 @@
|
|||||||
'hasDontEnumBug',
|
'hasDontEnumBug',
|
||||||
'isKeysFast',
|
'isKeysFast',
|
||||||
'objectLoop',
|
'objectLoop',
|
||||||
'noArgsEnum',
|
'nonEnumArgs',
|
||||||
'noCharByIndex',
|
'noCharByIndex',
|
||||||
'shadowed',
|
'shadowed',
|
||||||
'top',
|
'top',
|
||||||
@@ -903,6 +903,29 @@
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all `argsAreObjects` references from `source`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} source The source to process.
|
||||||
|
* @returns {String} Returns the modified source.
|
||||||
|
*/
|
||||||
|
function removeArgsAreObjects(source) {
|
||||||
|
source = removeVar(source, 'argsAreObjects');
|
||||||
|
|
||||||
|
// remove `argsAreObjects` from `_.isArray`
|
||||||
|
source = source.replace(matchFunction(source, 'isArray'), function(match) {
|
||||||
|
return match.replace(/\(argsAreObjects && *([^)]+)\)/g, '$1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove `argsAreObjects` from `_.isEqual`
|
||||||
|
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
|
||||||
|
return match.replace(/!argsAreObjects[^:]+:\s*/g, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all `noArgsClass` references from `source`.
|
* Removes all `noArgsClass` references from `source`.
|
||||||
*
|
*
|
||||||
@@ -918,11 +941,6 @@
|
|||||||
return match.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '');
|
return match.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove `noArgsClass` from `_.isEqual`
|
|
||||||
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
|
|
||||||
return match.replace(/noArgsClass[^:]+:\s*/g, '');
|
|
||||||
});
|
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1628,9 +1646,11 @@
|
|||||||
' }'
|
' }'
|
||||||
].join('\n'));
|
].join('\n'));
|
||||||
|
|
||||||
// remove `arguments` object check from `_.isEqual`
|
// remove `arguments` object and `argsAreObjects` check from `_.isEqual`
|
||||||
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
|
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
|
||||||
return match.replace(/^ *if *\(.+== argsClass[^}]+}\n/gm, '')
|
return match
|
||||||
|
.replace(/^ *if *\(.+== argsClass[^}]+}\n/gm, '')
|
||||||
|
.replace(/!argsAreObjects[^:]+:\s*/g, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove conditional `charCodeCallback` use from `_.max` and `_.min`
|
// remove conditional `charCodeCallback` use from `_.max` and `_.min`
|
||||||
@@ -1816,8 +1836,9 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source = removeIsArgumentsFallback(source);
|
source = removeArgsAreObjects(source);
|
||||||
source = removeHasObjectSpliceBug(source);
|
source = removeHasObjectSpliceBug(source);
|
||||||
|
source = removeIsArgumentsFallback(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove `thisArg` from unexposed `forIn` and `forOwn`
|
// remove `thisArg` from unexposed `forIn` and `forOwn`
|
||||||
@@ -1834,10 +1855,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `noArgsEnum` declarations and assignments
|
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `nonEnumArgs` declarations and assignments
|
||||||
source = source
|
source = source
|
||||||
.replace(/^ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/m, '')
|
.replace(/^ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/m, '')
|
||||||
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var (?:hasDontEnumBug|iteratesOwnLast|noArgsEnum).+\n/g, '');
|
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var (?:hasDontEnumBug|iteratesOwnLast|nonEnumArgs).+\n/g, '');
|
||||||
|
|
||||||
// remove `iteratesOwnLast` from `shimIsPlainObject`
|
// remove `iteratesOwnLast` from `shimIsPlainObject`
|
||||||
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) {
|
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) {
|
||||||
@@ -2008,7 +2029,7 @@
|
|||||||
}
|
}
|
||||||
if ((source.match(/\bcreateIterator\b/g) || []).length < 2) {
|
if ((source.match(/\bcreateIterator\b/g) || []).length < 2) {
|
||||||
source = removeFunction(source, 'createIterator');
|
source = removeFunction(source, 'createIterator');
|
||||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var noArgsEnum;|.+?noArgsEnum *=.+/g, '');
|
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var nonEnumArgs;|.+?nonEnumArgs *=.+/g, '');
|
||||||
}
|
}
|
||||||
if (isRemoved(source, 'createIterator', 'bind', 'keys', 'template')) {
|
if (isRemoved(source, 'createIterator', 'bind', 'keys', 'template')) {
|
||||||
source = removeVar(source, 'isBindFast');
|
source = removeVar(source, 'isBindFast');
|
||||||
@@ -2027,8 +2048,8 @@
|
|||||||
source = removeVar(source, 'nativeKeys');
|
source = removeVar(source, 'nativeKeys');
|
||||||
source = removeKeysOptimization(source);
|
source = removeKeysOptimization(source);
|
||||||
}
|
}
|
||||||
if (!source.match(/var (?:hasDontEnumBug|iteratesOwnLast|noArgsEnum)\b/g)) {
|
if (!source.match(/var (?:hasDontEnumBug|iteratesOwnLast|nonEnumArgs)\b/g)) {
|
||||||
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `noArgsEnum` assignments
|
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `nonEnumArgs` assignments
|
||||||
source = source.replace(/ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/, '');
|
source = source.replace(/ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
'hasDontEnumBug',
|
'hasDontEnumBug',
|
||||||
'isKeysFast',
|
'isKeysFast',
|
||||||
'objectLoop',
|
'objectLoop',
|
||||||
'noArgsEnum',
|
'nonEnumArgs',
|
||||||
'noCharByIndex',
|
'noCharByIndex',
|
||||||
'shadowed',
|
'shadowed',
|
||||||
'top',
|
'top',
|
||||||
|
|||||||
21
lodash.js
21
lodash.js
@@ -150,20 +150,23 @@
|
|||||||
arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
|
arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
|
||||||
|
|
||||||
/** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */
|
/** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */
|
||||||
var noArgsEnum = true;
|
var nonEnumArgs = true;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var props = [];
|
var props = [];
|
||||||
function ctor() { this.x = 1; }
|
function ctor() { this.x = 1; }
|
||||||
ctor.prototype = { 'valueOf': 1, 'y': 1 };
|
ctor.prototype = { 'valueOf': 1, 'y': 1 };
|
||||||
for (var prop in new ctor) { props.push(prop); }
|
for (var prop in new ctor) { props.push(prop); }
|
||||||
for (prop in arguments) { noArgsEnum = !prop; }
|
for (prop in arguments) { nonEnumArgs = !prop; }
|
||||||
|
|
||||||
hasDontEnumBug = !/valueOf/.test(props);
|
hasDontEnumBug = !/valueOf/.test(props);
|
||||||
iteratesOwnLast = props[0] != 'x';
|
iteratesOwnLast = props[0] != 'x';
|
||||||
}(1));
|
}(1));
|
||||||
|
|
||||||
/** Detect if an `arguments` object's [[Class]] is unresolvable (Firefox < 4, IE < 9) */
|
/** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
|
||||||
|
var argsAreObjects = arguments.constructor == Object;
|
||||||
|
|
||||||
|
/** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */
|
||||||
var noArgsClass = !isArguments(arguments);
|
var noArgsClass = !isArguments(arguments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -375,7 +378,7 @@
|
|||||||
|
|
||||||
// object iteration:
|
// object iteration:
|
||||||
// add support for iterating over `arguments` objects if needed
|
// add support for iterating over `arguments` objects if needed
|
||||||
' <% } else if (noArgsEnum) { %>\n' +
|
' <% } else if (nonEnumArgs) { %>\n' +
|
||||||
' var length = iteratee.length; index = -1;\n' +
|
' var length = iteratee.length; index = -1;\n' +
|
||||||
' if (length && isArguments(iteratee)) {\n' +
|
' if (length && isArguments(iteratee)) {\n' +
|
||||||
' while (++index < length) {\n' +
|
' while (++index < length) {\n' +
|
||||||
@@ -438,7 +441,7 @@
|
|||||||
' }' +
|
' }' +
|
||||||
' <% } %>' +
|
' <% } %>' +
|
||||||
' <% } %>' +
|
' <% } %>' +
|
||||||
' <% if (arrayLoop || noArgsEnum) { %>\n}<% } %>\n' +
|
' <% if (arrayLoop || nonEnumArgs) { %>\n}<% } %>\n' +
|
||||||
|
|
||||||
// add code to the bottom of the iteration function
|
// add code to the bottom of the iteration function
|
||||||
'<%= bottom %>;\n' +
|
'<%= bottom %>;\n' +
|
||||||
@@ -660,7 +663,7 @@
|
|||||||
'hasDontEnumBug': hasDontEnumBug,
|
'hasDontEnumBug': hasDontEnumBug,
|
||||||
'isKeysFast': isKeysFast,
|
'isKeysFast': isKeysFast,
|
||||||
'objectLoop': '',
|
'objectLoop': '',
|
||||||
'noArgsEnum': noArgsEnum,
|
'nonEnumArgs': nonEnumArgs,
|
||||||
'noCharByIndex': noCharByIndex,
|
'noCharByIndex': noCharByIndex,
|
||||||
'shadowed': shadowed,
|
'shadowed': shadowed,
|
||||||
'top': '',
|
'top': '',
|
||||||
@@ -1202,7 +1205,7 @@
|
|||||||
var isArray = nativeIsArray || function(value) {
|
var isArray = nativeIsArray || function(value) {
|
||||||
// `instanceof` may cause a memory leak in IE 7 if `value` is a host object
|
// `instanceof` may cause a memory leak in IE 7 if `value` is a host object
|
||||||
// http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
|
// http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
|
||||||
return value instanceof Array || toString.call(value) == arrayClass;
|
return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1373,8 +1376,8 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// in older versions of Opera, `arguments` objects have `Array` constructors
|
// in older versions of Opera, `arguments` objects have `Array` constructors
|
||||||
var ctorA = noArgsClass && isArguments(a) ? Object : a.constructor,
|
var ctorA = !argsAreObjects && isArguments(a) ? Object : a.constructor,
|
||||||
ctorB = noArgsClass && isArguments(b) ? Object : b.constructor;
|
ctorB = !argsAreObjects && isArguments(b) ? Object : b.constructor;
|
||||||
|
|
||||||
// non `Object` object instances with different constructors are not equal
|
// non `Object` object instances with different constructors are not equal
|
||||||
if (ctorA != ctorB && !(
|
if (ctorA != ctorB && !(
|
||||||
|
|||||||
Reference in New Issue
Block a user