mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 10:57:49 +00:00
Use WeakMaps if available to store function metadata.
This commit is contained in:
55
lodash.js
55
lodash.js
@@ -121,7 +121,8 @@
|
|||||||
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
|
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
|
||||||
'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document',
|
'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document',
|
||||||
'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
|
'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
|
||||||
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'window', 'WinRTError'
|
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
|
||||||
|
'window', 'WinRTError'
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Used to fix the JScript `[[DontEnum]]` bug */
|
/** Used to fix the JScript `[[DontEnum]]` bug */
|
||||||
@@ -693,7 +694,8 @@
|
|||||||
setTimeout = context.setTimeout,
|
setTimeout = context.setTimeout,
|
||||||
splice = arrayProto.splice,
|
splice = arrayProto.splice,
|
||||||
Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array,
|
Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array,
|
||||||
unshift = arrayProto.unshift;
|
unshift = arrayProto.unshift,
|
||||||
|
WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap;
|
||||||
|
|
||||||
/** Used to clone array buffers */
|
/** Used to clone array buffers */
|
||||||
var Float64Array = (function() {
|
var Float64Array = (function() {
|
||||||
@@ -733,6 +735,9 @@
|
|||||||
/** Used as the size, in bytes, of each Float64Array element */
|
/** Used as the size, in bytes, of each Float64Array element */
|
||||||
var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
|
var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
|
||||||
|
|
||||||
|
/** Used to store function metadata */
|
||||||
|
var metaMap = WeakMap && new WeakMap;
|
||||||
|
|
||||||
/** Used to lookup a built-in constructor by [[Class]] */
|
/** Used to lookup a built-in constructor by [[Class]] */
|
||||||
var ctorByClass = {};
|
var ctorByClass = {};
|
||||||
ctorByClass[float32Class] = context.Float32Array;
|
ctorByClass[float32Class] = context.Float32Array;
|
||||||
@@ -1360,7 +1365,7 @@
|
|||||||
if (typeof thisArg == 'undefined') {
|
if (typeof thisArg == 'undefined') {
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
var data = func[EXPANDO];
|
var data = getData(func);
|
||||||
if (typeof data == 'undefined') {
|
if (typeof data == 'undefined') {
|
||||||
if (support.funcNames) {
|
if (support.funcNames) {
|
||||||
data = !func.name;
|
data = !func.name;
|
||||||
@@ -2130,7 +2135,7 @@
|
|||||||
*/
|
*/
|
||||||
function basePartial(func, bitmask, args, holders, thisArg) {
|
function basePartial(func, bitmask, args, holders, thisArg) {
|
||||||
if (func) {
|
if (func) {
|
||||||
var data = func[EXPANDO],
|
var data = getData(func),
|
||||||
arity = data ? data[2] : func.length;
|
arity = data ? data[2] : func.length;
|
||||||
|
|
||||||
arity -= args.length;
|
arity -= args.length;
|
||||||
@@ -2718,7 +2723,7 @@
|
|||||||
isPartialRight = false;
|
isPartialRight = false;
|
||||||
partialRightArgs = partialRightHolders = null;
|
partialRightArgs = partialRightHolders = null;
|
||||||
}
|
}
|
||||||
var data = !isBindKey && func[EXPANDO];
|
var data = !isBindKey && getData(func);
|
||||||
if (data && data !== true) {
|
if (data && data !== true) {
|
||||||
var funcBitmask = data[1],
|
var funcBitmask = data[1],
|
||||||
funcIsBind = funcBitmask & BIND_FLAG,
|
funcIsBind = funcBitmask & BIND_FLAG,
|
||||||
@@ -2783,6 +2788,23 @@
|
|||||||
return argCount ? result(func, thisArg, argCount) : result;
|
return argCount ? result(func, thisArg, argCount) : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets metadata for `func`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Function} func The function to query.
|
||||||
|
* @returns {*} Returns the metadata for `func`.
|
||||||
|
*/
|
||||||
|
function getData(func) {
|
||||||
|
return metaMap.get(func);
|
||||||
|
}
|
||||||
|
// fallback for environments without `WeakMap`
|
||||||
|
if (!WeakMap) {
|
||||||
|
getData = !defineProperty ? noop : function(func) {
|
||||||
|
return func[EXPANDO];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the appropriate "indexOf" function. If the `_.indexOf` method is
|
* Gets the appropriate "indexOf" function. If the `_.indexOf` method is
|
||||||
* customized this function returns the custom method, otherwise it returns
|
* customized this function returns the custom method, otherwise it returns
|
||||||
@@ -2986,19 +3008,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets wrapper metadata on a given function.
|
* Sets metadata for `func`.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {Function} func The function to set data on.
|
* @param {Function} func The function to associate metadata with.
|
||||||
* @param {Array} value The data array to set.
|
* @param {*} data The metadata.
|
||||||
* @returns {Function} Returns `func`.
|
* @returns {Function} Returns `func`.
|
||||||
*/
|
*/
|
||||||
var setData = !defineProperty ? identity : function(func, value) {
|
function setData(func, data) {
|
||||||
descriptor.value = value;
|
metaMap.set(func, data);
|
||||||
defineProperty(func, EXPANDO, descriptor);
|
|
||||||
descriptor.value = null;
|
|
||||||
return func;
|
return func;
|
||||||
};
|
}
|
||||||
|
// fallback for environments without `WeakMap`
|
||||||
|
if (!WeakMap) {
|
||||||
|
setData = !defineProperty ? identity : function(func, value) {
|
||||||
|
descriptor.value = value;
|
||||||
|
defineProperty(func, EXPANDO, descriptor);
|
||||||
|
descriptor.value = null;
|
||||||
|
return func;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fallback implementation of `_.isPlainObject` which checks if `value`
|
* A fallback implementation of `_.isPlainObject` which checks if `value`
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
var hasOwnProperty = objectProto.hasOwnProperty,
|
var hasOwnProperty = objectProto.hasOwnProperty,
|
||||||
fnToString = funcProto.toString,
|
fnToString = funcProto.toString,
|
||||||
nativeString = fnToString.call(objectProto.toString),
|
nativeString = fnToString.call(objectProto.toString),
|
||||||
noop = function() {},
|
noop = function() { },
|
||||||
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
||||||
reToString = /toString/g,
|
reToString = /toString/g,
|
||||||
whitespace = ' \t\x0B\f\xA0\ufeff\n\r\u2028\u2029\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000';
|
whitespace = ' \t\x0B\f\xA0\ufeff\n\r\u2028\u2029\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000';
|
||||||
@@ -154,6 +154,9 @@
|
|||||||
return Float64Array;
|
return Float64Array;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
setProperty(window, '_WeakMap', window.WeakMap);
|
||||||
|
setProperty(window, 'WeakMap', noop);
|
||||||
|
|
||||||
setProperty(window, '_parseInt', parseInt);
|
setProperty(window, '_parseInt', parseInt);
|
||||||
setProperty(window, 'parseInt', (function(_parseInt) {
|
setProperty(window, 'parseInt', (function(_parseInt) {
|
||||||
var checkStr = whitespace + '08',
|
var checkStr = whitespace + '08',
|
||||||
@@ -235,6 +238,11 @@
|
|||||||
}
|
}
|
||||||
setProperty(window, '_ArrayBuffer', undefined);
|
setProperty(window, '_ArrayBuffer', undefined);
|
||||||
|
|
||||||
|
if (window._WeakMap) {
|
||||||
|
WeakMap = _WeakMap;
|
||||||
|
}
|
||||||
|
setProperty(window, '_WeakMap', undefined);
|
||||||
|
|
||||||
setProperty(window, 'parseInt', window._parseInt);
|
setProperty(window, 'parseInt', window._parseInt);
|
||||||
setProperty(window, '_parseInt', undefined);
|
setProperty(window, '_parseInt', undefined);
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
slice = arrayProto.slice,
|
slice = arrayProto.slice,
|
||||||
system = root.system,
|
system = root.system,
|
||||||
toString = objectProto.toString,
|
toString = objectProto.toString,
|
||||||
Uint8Array = root.Uint8Array;
|
Uint8Array = root.Uint8Array,
|
||||||
|
WeakMap = root.WeakMap;
|
||||||
|
|
||||||
/** The file path of the Lo-Dash file to test */
|
/** The file path of the Lo-Dash file to test */
|
||||||
var filePath = (function() {
|
var filePath = (function() {
|
||||||
@@ -2179,7 +2180,7 @@
|
|||||||
|
|
||||||
var object = {};
|
var object = {};
|
||||||
|
|
||||||
if (defineProperty && _.support.funcDecomp) {
|
if ((defineProperty && !WeakMap) && _.support.funcDecomp) {
|
||||||
_.callback(a, object);
|
_.callback(a, object);
|
||||||
ok(EXPANDO in a);
|
ok(EXPANDO in a);
|
||||||
|
|
||||||
@@ -2205,7 +2206,7 @@
|
|||||||
test('should not write metadata when `_.support.funcDecomp` is `false`', 1, function() {
|
test('should not write metadata when `_.support.funcDecomp` is `false`', 1, function() {
|
||||||
function a() {};
|
function a() {};
|
||||||
|
|
||||||
if (defineProperty && lodashBizarro) {
|
if ((defineProperty && !WeakMap) && lodashBizarro) {
|
||||||
lodashBizarro.callback(a, {});
|
lodashBizarro.callback(a, {});
|
||||||
ok(!(EXPANDO in a));
|
ok(!(EXPANDO in a));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user