Isarraylike detection is an array object or a pure array
varproperty =function(key) {return function(obj) {returnobj = =NULL?void0: Obj[key]; }; }; varGetLength = Property (' Length '); varIsarraylike =function(collection) {varLength =GetLength (collection); return typeofLength = = ' number ' && length >= 0 && length <=Max_array_index; };
From the bottom up see property Isarraylike-GetLength
property is a closed package
After simplification:
GetLength returns a function
var getlength = function(obj) { return obj[' length '];}
When calling
collection = [A]
var length = GetLength (collection);
var function (collection) { // var length = [1,2,3][' length ']; var length = getlength (collection); return typeof Length = = ' number ' && length >= 0 && length <= max_array_index; };
T5. html
<!DOCTYPE HTML><HTML><Head><MetaCharSet= "Utf-8" /><title>Underscore</title><Scriptsrc= "Underscore.js"></Script></Head><Body></Body></HTML><Scripttype= "Text/javascript"src= "T5.js"></Script>
T5.js
_.each ([1, 2, 3], alert);
Execution Process :
1. The OPTIMIZECB function is then entered.
//obj = [Iteratee], = alert (), context = undefined_.each = _.foreach =function(obj, iteratee, context) {Iteratee=OPTIMIZECB (iteratee, context); vari, length; if(Isarraylike (obj)) { for(i = 0, length = obj.length; i < length; i++) {iteratee (obj[i], I, obj); } } Else { varKeys =_.keys (obj); for(i = 0, length = keys.length; i < length; i++) {iteratee (Obj[keys[i]], keys[i], obj); } } returnobj; };
2. Optimizecb function
//Internal function that returns a efficient (for current engines) version //of the passed-in callback, to is repeatedly applied in other underscore //functions. varOPTIMIZECB =function(func, Context, Argcount) {if(Context = = =void0)returnfunc; Switch(Argcount = =NULL? 3: Argcount) { Case1:return function(value) {returnFunc.call (context, value); }; //The 2-parameter case had been omitted only because no current consumers //made use of it. Case3:return function(value, index, collection) {returnFunc.call (context, value, index, collection); }; Case4:return function(accumulator, value, index, collection) {returnFunc.call (context, accumulator, value, index, collection); }; } return function() { returnfunc.apply (context, arguments); }; };
Because Argcount = underfined. None of the conditions in switch are satisfied.
Equal to the direct execution.
return function() { return func.apply (context, arguments); };
3. Isarraylike above has been analyzed
var function (collection) { var length = getlength (collection); return typeof Length = = ' number ' && length >= 0 && length <= max_array_index; };
Returns True
4.
// then execute the if (Isarraylike (obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee (Obj[i], I, obj); } }
Tips:
1. Context = = = void 0 Determines whether the context is undefined. Specific explanations
Underscore.js Source Code Analysis 5 basic functions and the use of each function