Add hasEnumPrototype to avoid including the fix if not needed.

Former-commit-id: f826b725180a95d41b66612919c8b3fddfe568a0
This commit is contained in:
John-David Dalton
2013-02-01 01:24:34 -08:00
parent c3b984fea7
commit 8adb060edb
3 changed files with 33 additions and 15 deletions

View File

@@ -177,6 +177,7 @@
'bottom',
'firstArg',
'hasDontEnumBug',
'hasEnumPrototype',
'isKeysFast',
'loop',
'nonEnumArgs',
@@ -1924,8 +1925,9 @@
// remove `prototype` [[Enumerable]] fix from `iteratorTemplate`
source = source.replace(getIteratorTemplate(source), function(match) {
return match
.replace(/(?: *\/\/.*\n)* *["'] *(?:<% *)?if *\(!hasDontEnumBug *(?:&&|\))[\s\S]+?<% *} *(?:%>|["']).+/g, '')
.replace(/!hasDontEnumBug *\|\|/g, '');
.replace(/(?: *\/\/.*\n)* *["']( *)<% *if *\(hasDontEnumBug[\s\S]+?["']\1<% *} *%>.+/, '')
.replace(/(?: *\/\/.*\n)* *["'] *(?:<% *)?if *\(hasEnumPrototype *(?:&&|\))[\s\S]+?<% *} *(?:%>|["']).+/g, '')
.replace(/hasEnumPrototype *\|\|/g, '');
});
}
vm.runInContext(source, context);
@@ -2095,10 +2097,10 @@
}
});
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `nonEnumArgs` declarations and assignments
// remove `hasDontEnumBug`, `hasEnumPrototype`, `iteratesOwnLast`, and `nonEnumArgs` declarations and assignments
source = source
.replace(/^ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/m, '')
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var (?:hasDontEnumBug|iteratesOwnLast|nonEnumArgs).+\n/g, '');
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var (?:hasDontEnumBug|hasEnumPrototype|iteratesOwnLast|nonEnumArgs).+\n/g, '')
.replace(/^ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/m, '');
// remove `iteratesOwnLast` from `shimIsPlainObject`
source = source.replace(matchFunction(source, 'shimIsPlainObject'), function(match) {
@@ -2256,6 +2258,7 @@
if ((source.match(/\bcreateIterator\b/g) || []).length < 2) {
source = removeFunction(source, 'createIterator');
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasDontEnumBug;|.+?hasDontEnumBug *=.+/g, '');
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var hasEnumPrototype;|.+?hasEnumPrototype *=.+/g, '');
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *var nonEnumArgs;|.+?nonEnumArgs *=.+/g, '');
}
if (isRemoved(source, 'createIterator', 'bind', 'keys')) {
@@ -2267,8 +2270,8 @@
source = removeVar(source, 'nativeKeys');
source = removeKeysOptimization(source);
}
if (!source.match(/var (?:hasDontEnumBug|iteratesOwnLast|nonEnumArgs)\b/g)) {
// remove `hasDontEnumBug`, `iteratesOwnLast`, and `nonEnumArgs` assignments
if (!source.match(/var (?:hasDontEnumBug|hasEnumPrototype|iteratesOwnLast|nonEnumArgs)\b/g)) {
// remove `hasDontEnumBug`, `hasEnumPrototype`, `iteratesOwnLast`, and `nonEnumArgs` assignments
source = source.replace(/ *\(function\(\) *{[\s\S]+?}\(1\)\);\n/, '');
}
}

View File

@@ -40,6 +40,7 @@
'bottom',
'firstArg',
'hasDontEnumBug',
'hasEnumPrototype',
'isKeysFast',
'loop',
'nonEnumArgs',

View File

@@ -127,6 +127,18 @@
*/
var hasDontEnumBug;
/**
* Detect if a `prototype` properties are enumerable by default:
*
* Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
* (if the prototype or a property on the prototype has been set)
* incorrectly sets a function's `prototype` property [[Enumerable]]
* value to `true`. Because of this Lo-Dash standardizes on skipping
* the the `prototype` property of functions regardless of its
* [[Enumerable]] value.
*/
var hasEnumPrototype;
/** Detect if own properties are iterated after inherited properties (IE < 9) */
var iteratesOwnLast;
@@ -154,6 +166,7 @@
for (prop in arguments) { nonEnumArgs = !prop; }
hasDontEnumBug = !/valueOf/.test(props);
hasEnumPrototype = propertyIsEnumerable.call(ctor, 'prototype');
iteratesOwnLast = props[0] != 'x';
}(1));
@@ -385,7 +398,7 @@
// value to `true`. Because of this Lo-Dash standardizes on skipping
// the the `prototype` property of functions regardless of its
// [[Enumerable]] value.
' <% if (!hasDontEnumBug) { %>\n' +
' <% if (hasEnumPrototype) { %>\n' +
" var skipProto = typeof iterable == 'function' && \n" +
" propertyIsEnumerable.call(iterable, 'prototype');\n" +
' <% } %>' +
@@ -397,22 +410,22 @@
' length = ownProps.length;\n\n' +
' while (++ownIndex < length) {\n' +
' index = ownProps[ownIndex];\n' +
" <% if (!hasDontEnumBug) { %>if (!(skipProto && index == 'prototype')) {\n <% } %>" +
" <% if (hasEnumPrototype) { %>if (!(skipProto && index == 'prototype')) {\n <% } %>" +
' <%= loop %>\n' +
' <% if (!hasDontEnumBug) { %>}\n<% } %>' +
' <% if (hasEnumPrototype) { %>}\n<% } %>' +
' }' +
// else using a for-in loop
' <% } else { %>\n' +
' for (index in iterable) {<%' +
' if (!hasDontEnumBug || useHas) { %>\n if (<%' +
" if (!hasDontEnumBug) { %>!(skipProto && index == 'prototype')<% }" +
' if (!hasDontEnumBug && useHas) { %> && <% }' +
' if (hasEnumPrototype || useHas) { %>\n if (<%' +
" if (hasEnumPrototype) { %>!(skipProto && index == 'prototype')<% }" +
' if (hasEnumPrototype && useHas) { %> && <% }' +
' if (useHas) { %>hasOwnProperty.call(iterable, index)<% }' +
' %>) {' +
' <% } %>\n' +
' <%= loop %>;' +
' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' +
' <% if (hasEnumPrototype || useHas) { %>\n }<% } %>\n' +
' }' +
' <% } %>' +
@@ -678,6 +691,7 @@
var data = {
// support properties
'hasDontEnumBug': hasDontEnumBug,
'hasEnumPrototype': hasEnumPrototype,
'isKeysFast': isKeysFast,
'nonEnumArgs': nonEnumArgs,
'noCharByIndex': noCharByIndex,
@@ -931,7 +945,7 @@
*/
var keys = !nativeKeys ? shimKeys : function(object) {
// avoid iterating over the `prototype` property
return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype')
return hasEnumPrototype && typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype')
? shimKeys(object)
: (isObject(object) ? nativeKeys(object) : []);
};