var forEach = (function(){
//Array and Pseudo array traversal
var _Array_forEach = function (array, block, context) {
if (array == null) return;
//Special processing for String
if(typeof array == 'string'){
array = array.split('');
}
var i = 0,length = array.length;
for (;i < length && block.call (context, array[i], (i 1), array)!==false; i ) {}
};
//Traversal of objects
var _Function_forEach = function (object, block, context ) {
for (var key in object) {
//Only traverse local properties
if (object.hasOwnProperty(key)&&block.call(context, object[key], key, object)== =false){
break;
}
}
};
return function(object, block, context){
if (object == null) return;
if (typeof object.length == "number") {
_Array_forEach(object, block, context);
}else{
_Function_forEach(object, block, context);
}
};
})()
The function itself is not complicated, but it is very delicate. I added some simple comments, I hope everyone can understand it.
Let’s look at some examples
//1:1 n 2:2
forEach([1,2,3,4,5],function(el,index){
if(index>2){
return false;
}
alert(index ":" el);
});
function print(el,index){
alert(index ":" el);
}
//a: a n b:b n c:c
forEach({a:'a',b:'b',c:'c'},print);
//1: stupid n 2: egg n 3: n 4: seat n 5: right n 6: inscription
forEach("Idiot's motto",print);
function Person(name, age) {
this.name = name || "";
this.age = age || 0;
};
Person.prototype = new Person;
var fred = new Person("jxl", 22);
fred.language = " chinese";//Extremely late binding
//name:jxl n age:22 n language:chinese
forEach(fred,print);
Note: in the callback function The index parameter subscript starts from 1
Why not use the built-in forEach
Like getElementsByClassName, the built-in forEach is very efficient, but it has limitations in function. It cannot exit in the middle of the loop. In our forEach, it can exit the loop by returning false within the processing function, which is more flexible.
Special length attribute
The length attribute is a very special attribute. When you see an array, you will definitely think of length. What about an object with a length attribute? Then everyone must think of pseudo arrays (array-like). So what is a pseudo array? The simple understanding is that it can be converted into an object with the length attribute of a real array through Array.prototype.slice. The most famous pseudo-array in JavaScript is the arguments object. There are a lot of things about pseudo-arrays, and I will write a blog post about this in the future. Everyone just needs to remember: Don't assign the length attribute to an object casually, unless you clearly know that you are going to use it as a pseudo array.
I think this function is a necessary function in a simple JavaScript tool library. It is the foundation of the pyramid. Based on it, re-encapsulation can make your library more powerful and beautiful!