You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Monkey patchArray.prototype.forEach=Array.prototype.forEach||forEachfunctionforEach(callback,thisArg){varobject=newObject(this)// 如果this是字符串则转换为数组varself=isString(this) ? this.split('') : objectvari=-1// robust检查if(!self.length)thrownewTypeError(self+'isn\'t an array.')if(!isFn(callback))thrownewTypeError('Array.prototype.forEach callback must be a function')while(++i<self.length){// 如果this的属性不为number或该index的属性不存在,则不遍历(确保为类数组遍历)if(iinself){// 若存在thisArg,增加调用时回调函数this指向if(thisArg){callback.call(thisArg,self[i],i,object)}else{callback(self[i],i,object)}}}}functionisString(str){returnObject.prototype.toString.call(str)==='[object String]'}functionisFn(fn){returnObject.prototype.toString.call(str)==='[object Function]'}
functionmap(callback,thisArg){varobject=newObject(this)varself=isString(this) ? this.split('') : objectvari=-1// 生成的新数组varresult=[]if(!self.length)thrownewTypeError(self+'isn\'t an array.')if(!isFn(callback))thrownewTypeError('Array.prototype.forEach callback must be a function')while(++i<self.length){if(iinself){if(thisArg){// 赋值result[i]=callback.call(thisArg,self[i],i,object)}else{result[i]=callback(self[i],i,object)}}}// 返回新数组returnresult}
目标
思路
深入
前面说到map, every, some, filter与forEach的结构其实大同小异,主要是while内部的逻辑有所不同。其实这里实现的forEach, map等都属于内部迭代器,forEach函数内部定义了迭代规则,外部只需一次初始调用即可。同时,由于是内部迭代器,每需要一种不同的迭代功能,就得写一份类似的代码,较为复杂的迭代需求就不方便通过写好的迭代函数来实现了,大部分情况下我们会重新封装一个带for () {}语句的函数以复用。
这时候我们来看看外部迭代器能替我们解决什么问题。外部迭代器相当于将迭代的功能装在了数据结构上,增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,减少了结构性的代码,基本写出来的都是需求的逻辑。
下面就是一个外部迭代器的实现,代码来自《JavaScript设计模式与开发实践》P105:
基于Class版:
总结
那么使用外部迭代器和直接使用循环语句写逻辑有什么不同呢,很大程度上,使用外部迭代器减少了循环的嵌套,使代码更清晰,这在多重迭代上体现的尤为明显。如果需求只有一层循环,那大可直接使用循环语句。
The text was updated successfully, but these errors were encountered: