mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 10:17:48 +00:00
Optimize _.isFunction.
Former-commit-id: 0aaaa6d166c7eea94237388d61a11c6d183cbe1f
This commit is contained in:
1
build.js
1
build.js
@@ -857,7 +857,6 @@
|
|||||||
// build replacement code
|
// build replacement code
|
||||||
lodash.forOwn({
|
lodash.forOwn({
|
||||||
'Date': 'dateClass',
|
'Date': 'dateClass',
|
||||||
'Function': 'funcClass',
|
|
||||||
'Number': 'numberClass',
|
'Number': 'numberClass',
|
||||||
'RegExp': 'regexpClass',
|
'RegExp': 'regexpClass',
|
||||||
'String': 'stringClass'
|
'String': 'stringClass'
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
'isArr',
|
'isArr',
|
||||||
'isArray',
|
'isArray',
|
||||||
'isFunc',
|
'isFunc',
|
||||||
|
'isFunction',
|
||||||
'isPlainObject',
|
'isPlainObject',
|
||||||
'methodName',
|
'methodName',
|
||||||
'noaccum',
|
'noaccum',
|
||||||
|
|||||||
207
lodash.js
207
lodash.js
@@ -663,8 +663,8 @@
|
|||||||
var factory = Function(
|
var factory = Function(
|
||||||
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn, ' +
|
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn, ' +
|
||||||
'funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray, ' +
|
'funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray, ' +
|
||||||
'isPlainObject, iteratorBind, objectClass, objectTypes, nativeKeys, ' +
|
'isFunction, isPlainObject, iteratorBind, objectClass, objectTypes, ' +
|
||||||
'propertyIsEnumerable, slice, stringClass, toString',
|
'nativeKeys, propertyIsEnumerable, slice, stringClass, toString',
|
||||||
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
||||||
'return callee'
|
'return callee'
|
||||||
);
|
);
|
||||||
@@ -672,8 +672,8 @@
|
|||||||
return factory(
|
return factory(
|
||||||
arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn,
|
arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn,
|
||||||
funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray,
|
funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray,
|
||||||
isPlainObject, iteratorBind, objectClass, objectTypes, nativeKeys,
|
isFunction, isPlainObject, iteratorBind, objectClass, objectTypes,
|
||||||
propertyIsEnumerable, slice, stringClass, toString
|
nativeKeys, propertyIsEnumerable, slice, stringClass, toString
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,7 +751,7 @@
|
|||||||
// Also check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
// Also check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
||||||
var ctor = value.constructor;
|
var ctor = value.constructor;
|
||||||
if ((!noNodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&
|
if ((!noNodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&
|
||||||
(toString.call(ctor) != funcClass || ctor instanceof ctor)) {
|
(!isFunction(ctor) || ctor instanceof ctor)) {
|
||||||
// IE < 9 iterates inherited properties before own properties. If the first
|
// IE < 9 iterates inherited properties before own properties. If the first
|
||||||
// iterated property is an object's own property then there are no inherited
|
// iterated property is an object's own property then there are no inherited
|
||||||
// enumerable properties.
|
// enumerable properties.
|
||||||
@@ -856,6 +856,92 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is an `arguments` object.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Objects
|
||||||
|
* @param {Mixed} value The value to check.
|
||||||
|
* @returns {Boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* (function() { return _.isArguments(arguments); })(1, 2, 3);
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* _.isArguments([1, 2, 3]);
|
||||||
|
* // => false
|
||||||
|
*/
|
||||||
|
function isArguments(value) {
|
||||||
|
return toString.call(value) == argsClass;
|
||||||
|
}
|
||||||
|
// fallback for browsers that can't detect `arguments` objects by [[Class]]
|
||||||
|
if (noArgsClass) {
|
||||||
|
isArguments = function(value) {
|
||||||
|
return !!(value && hasOwnProperty.call(value, 'callee'));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is an array.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Objects
|
||||||
|
* @param {Mixed} value The value to check.
|
||||||
|
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* (function() { return _.isArray(arguments); })();
|
||||||
|
* // => false
|
||||||
|
*
|
||||||
|
* _.isArray([1, 2, 3]);
|
||||||
|
* // => true
|
||||||
|
*/
|
||||||
|
var isArray = nativeIsArray || function(value) {
|
||||||
|
return toString.call(value) == arrayClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is a function.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Objects
|
||||||
|
* @param {Mixed} value The value to check.
|
||||||
|
* @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* _.isFunction(''.concat);
|
||||||
|
* // => true
|
||||||
|
*/
|
||||||
|
function isFunction(value) {
|
||||||
|
return typeof value == 'function';
|
||||||
|
}
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return toString.call(value) == funcClass;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shim implementation of `Object.keys` that produces an array of the given
|
||||||
|
* object's own enumerable property names.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to inspect.
|
||||||
|
* @returns {Array} Returns a new array of property names.
|
||||||
|
*/
|
||||||
|
var shimKeys = createIterator({
|
||||||
|
'args': 'object',
|
||||||
|
'exit': 'if (!(object && objectTypes[typeof object])) throw TypeError()',
|
||||||
|
'init': '[]',
|
||||||
|
'inLoop': 'result.push(index)'
|
||||||
|
});
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of `value`. If `deep` is `true`, all nested objects will
|
* Creates a clone of `value`. If `deep` is `true`, all nested objects will
|
||||||
* also be cloned otherwise they will be assigned by reference. If a value has
|
* also be cloned otherwise they will be assigned by reference. If a value has
|
||||||
@@ -909,7 +995,7 @@
|
|||||||
}
|
}
|
||||||
// use custom `clone` method if available
|
// use custom `clone` method if available
|
||||||
var isObj = objectTypes[typeof value];
|
var isObj = objectTypes[typeof value];
|
||||||
if ((isObj || thorough.value) && value.clone && toString.call(value.clone) == funcClass) {
|
if ((isObj || thorough.value) && value.clone && isFunction(value.clone)) {
|
||||||
thorough.value = null;
|
thorough.value = null;
|
||||||
return value.clone(deep);
|
return value.clone(deep);
|
||||||
}
|
}
|
||||||
@@ -1114,7 +1200,7 @@
|
|||||||
'useHas': false,
|
'useHas': false,
|
||||||
'args': 'object',
|
'args': 'object',
|
||||||
'init': '[]',
|
'init': '[]',
|
||||||
'inLoop': 'if (toString.call(value) == funcClass) result.push(index)',
|
'inLoop': 'if (isFunction(value)) result.push(index)',
|
||||||
'bottom': 'result.sort()'
|
'bottom': 'result.sort()'
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1137,52 +1223,6 @@
|
|||||||
return hasOwnProperty.call(object, property);
|
return hasOwnProperty.call(object, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if `value` is an `arguments` object.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @memberOf _
|
|
||||||
* @category Objects
|
|
||||||
* @param {Mixed} value The value to check.
|
|
||||||
* @returns {Boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* (function() { return _.isArguments(arguments); })(1, 2, 3);
|
|
||||||
* // => true
|
|
||||||
*
|
|
||||||
* _.isArguments([1, 2, 3]);
|
|
||||||
* // => false
|
|
||||||
*/
|
|
||||||
function isArguments(value) {
|
|
||||||
return toString.call(value) == argsClass;
|
|
||||||
}
|
|
||||||
// fallback for browsers that can't detect `arguments` objects by [[Class]]
|
|
||||||
if (noArgsClass) {
|
|
||||||
isArguments = function(value) {
|
|
||||||
return !!(value && hasOwnProperty.call(value, 'callee'));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if `value` is an array.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @memberOf _
|
|
||||||
* @category Objects
|
|
||||||
* @param {Mixed} value The value to check.
|
|
||||||
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* (function() { return _.isArray(arguments); })();
|
|
||||||
* // => false
|
|
||||||
*
|
|
||||||
* _.isArray([1, 2, 3]);
|
|
||||||
* // => true
|
|
||||||
*/
|
|
||||||
var isArray = nativeIsArray || function(value) {
|
|
||||||
return toString.call(value) == arrayClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if `value` is a boolean (`true` or `false`) value.
|
* Checks if `value` is a boolean (`true` or `false`) value.
|
||||||
*
|
*
|
||||||
@@ -1264,7 +1304,7 @@
|
|||||||
'if (arrayLikeClasses[className]' +
|
'if (arrayLikeClasses[className]' +
|
||||||
(noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' +
|
(noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' +
|
||||||
' (className == objectClass && length > -1 && length === length >>> 0 &&\n' +
|
' (className == objectClass && length > -1 && length === length >>> 0 &&\n' +
|
||||||
' toString.call(value.splice) == funcClass)' +
|
' isFunction(value.splice))' +
|
||||||
') return !length',
|
') return !length',
|
||||||
'inLoop': {
|
'inLoop': {
|
||||||
'object': 'return false'
|
'object': 'return false'
|
||||||
@@ -1317,11 +1357,11 @@
|
|||||||
b = b._wrapped;
|
b = b._wrapped;
|
||||||
}
|
}
|
||||||
// use custom `isEqual` method if available
|
// use custom `isEqual` method if available
|
||||||
if (a.isEqual && toString.call(a.isEqual) == funcClass) {
|
if (a.isEqual && isFunction(a.isEqual)) {
|
||||||
thorough.value = null;
|
thorough.value = null;
|
||||||
return a.isEqual(b);
|
return a.isEqual(b);
|
||||||
}
|
}
|
||||||
if (b.isEqual && toString.call(b.isEqual) == funcClass) {
|
if (b.isEqual && isFunction(b.isEqual)) {
|
||||||
thorough.value = null;
|
thorough.value = null;
|
||||||
return b.isEqual(a);
|
return b.isEqual(a);
|
||||||
}
|
}
|
||||||
@@ -1408,8 +1448,8 @@
|
|||||||
|
|
||||||
// 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 && !(
|
||||||
toString.call(ctorA) == funcClass && ctorA instanceof ctorA &&
|
isFunction(ctorA) && ctorA instanceof ctorA &&
|
||||||
toString.call(ctorB) == funcClass && ctorB instanceof ctorB
|
isFunction(ctorB) && ctorB instanceof ctorB
|
||||||
)) {
|
)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1474,23 +1514,6 @@
|
|||||||
return nativeIsFinite(value) && toString.call(value) == numberClass;
|
return nativeIsFinite(value) && toString.call(value) == numberClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if `value` is a function.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @memberOf _
|
|
||||||
* @category Objects
|
|
||||||
* @param {Mixed} value The value to check.
|
|
||||||
* @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* _.isFunction(''.concat);
|
|
||||||
* // => true
|
|
||||||
*/
|
|
||||||
function isFunction(value) {
|
|
||||||
return toString.call(value) == funcClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if `value` is the language type of Object.
|
* Checks if `value` is the language type of Object.
|
||||||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||||||
@@ -1636,21 +1659,6 @@
|
|||||||
return value === undefined;
|
return value === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A shim implementation of `Object.keys` that produces an array of the given
|
|
||||||
* object's own enumerable property names.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object} object The object to inspect.
|
|
||||||
* @returns {Array} Returns a new array of property names.
|
|
||||||
*/
|
|
||||||
var shimKeys = createIterator({
|
|
||||||
'args': 'object',
|
|
||||||
'exit': 'if (!(object && objectTypes[typeof object])) throw TypeError()',
|
|
||||||
'init': '[]',
|
|
||||||
'inLoop': 'result.push(index)'
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array composed of the own enumerable property names of `object`.
|
* Creates an array composed of the own enumerable property names of `object`.
|
||||||
*
|
*
|
||||||
@@ -1738,8 +1746,7 @@
|
|||||||
// http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/chrome/reps.js?r=12614#653
|
// http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/chrome/reps.js?r=12614#653
|
||||||
// http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/InjectedScriptSource.js?rev=125186#L609
|
// http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/InjectedScriptSource.js?rev=125186#L609
|
||||||
if (arrayLikeClasses[className] || (noArgsClass && isArguments(value)) ||
|
if (arrayLikeClasses[className] || (noArgsClass && isArguments(value)) ||
|
||||||
(className == objectClass && length > -1 && length === length >>> 0 &&
|
(className == objectClass && length > -1 && length === length >>> 0 && isFunction(value.splice))) {
|
||||||
toString.call(value.splice) == funcClass)) {
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
return keys(value).length;
|
return keys(value).length;
|
||||||
@@ -2296,7 +2303,7 @@
|
|||||||
if (!collection) {
|
if (!collection) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (collection.toArray && toString.call(collection.toArray) == funcClass) {
|
if (collection.toArray && isFunction(collection.toArray)) {
|
||||||
return collection.toArray();
|
return collection.toArray();
|
||||||
}
|
}
|
||||||
var length = collection.length;
|
var length = collection.length;
|
||||||
@@ -3176,7 +3183,7 @@
|
|||||||
*/
|
*/
|
||||||
function bind(func, thisArg) {
|
function bind(func, thisArg) {
|
||||||
var methodName,
|
var methodName,
|
||||||
isFunc = toString.call(func) == funcClass;
|
isFunc = isFunction(func);
|
||||||
|
|
||||||
// juggle arguments
|
// juggle arguments
|
||||||
if (!isFunc) {
|
if (!isFunc) {
|
||||||
@@ -3253,13 +3260,15 @@
|
|||||||
'var funcs = arguments,\n' +
|
'var funcs = arguments,\n' +
|
||||||
' length = funcs.length;\n' +
|
' length = funcs.length;\n' +
|
||||||
'if (length > 1) {\n' +
|
'if (length > 1) {\n' +
|
||||||
' for (var index = 1; index < length; index++)\n' +
|
' for (var index = 1; index < length; index++) {\n' +
|
||||||
' result[funcs[index]] = bind(result[funcs[index]], result);\n' +
|
' result[funcs[index]] = bind(result[funcs[index]], result)\n' +
|
||||||
|
' }\n' +
|
||||||
' return result\n' +
|
' return result\n' +
|
||||||
'}',
|
'}',
|
||||||
'inLoop':
|
'inLoop':
|
||||||
'if (toString.call(result[index]) == funcClass)' +
|
'if (isFunction(result[index])) {\n' +
|
||||||
' result[index] = bind(result[index], result)'
|
' result[index] = bind(result[index], result)\n' +
|
||||||
|
'}'
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3691,7 +3700,7 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var value = object[property];
|
var value = object[property];
|
||||||
return toString.call(value) == funcClass ? object[property]() : value;
|
return isFunction(value) ? object[property]() : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user