each方法接受要遍历的对象和对应的回调函数作为参数,它的作用是:
1、如果要遍历的对象是类似数组的形式(以该对象的length属性值的类型是否为number类型来判断),那么就把以要遍历的对象为执行环境,将回调函数放到该执行环境中去循环执行length次;
2、如果要遍历的对象不类似数组,那么用for key in obj 的方法循环执行回调函数key次,同样以要遍历的对象为执行环境,将回调函数放到该执行环境中去循环执行。
function each(elements, callback){ //定义each的回调函数的参数 var i, key //如果elements参数的length是一个number类型,可能是数组、字符串、arguments对象等 if (typeof elements.length == "number") { for (i = 0; i < elements.length; i++) //call(thisObj,arg1,arg2,....); 第一个参数是执行环境对象,后面都是传递的数据 //如果回调函数在elements[i]这个执行环境中,使用i和elements[i]这两个参数执行的结果为null、undefined,那么将elements原样返回 if (callback.call(elements[i], i, elements[i]) === false) return elements } else { for (key in elements) if (callback.call(elements[key], key, elements[key]) === false) return elements } return elements };
用法很简单,就不举例子了。
因为正在学习this,所以我想知道在回调函数里面输出this是怎么个情况,于是我这样玩了一下:
var o = {"a":"sdfsdf","s":3}; each(o,function(i,ele){ console.log(this); });
在谷歌浏览器的console.log控制台居然是得到这样的结果:String {0: "s", 1: "d", 2: "f", 3: "s", 4: "d", 5: "f", length: 6, [[PrimitiveValue]]: "sdfsdf"}
这是因为回调函数的执行环境是elements[key],在本例中也就是o[a],而第一次遍历传入的参数也就成了o[a],而o[a]的值是一个字符串"sdfsdf",那么this很自然就指向了这个字符串对象
将字符串在console控制台作为一个对象输出时,自然就得到对象的属性树,但是如果是在html页面中使用document.write输出,那就会得到这个字符串的值;
以下例子可以证明:
function test(){ console.log(this); } var str = "sdfsdfsdf"; test.call(str); //在控制台得到:String {0: "s", 1: "d", 2: "f", 3: "s", 4: "d", 5: "f", 6: "s", 7: "d", 8: "f", length: 9, [[PrimitiveValue]]: "sdfsdfsdf"} //在html页面中输出得到字符串的值:sdfsdfsdf