作家
登录

Array.prototype.slice 使用扩展

作者: 来源:www.28hudong.com 2013-03-30 01:31:26 阅读 我要评论

除了正常用法,slice 经常用来将 array-like 对象转换为 true array. 名词解释:array-like object – 拥有 length 属性的对象,比如 { 0: ‘foo', length: 1 }, 甚至 { length: ‘bar' }. 最常见的 array-like 对象是 arguments 和 NodeList. 查看 V8 引擎 array.js 的源码,可以将 slice 的内部实现简化为: 复制代码 代码如下: function slice(start, end) { var len = ToUint32(this.length), result = []; for(var i = start; i < end; i++) { result.push(this[i]); } return result; } 可以看出,slice 并不需要 this 为 array 类型,只需要有 length 属性即可。并且 length 属性可以不为 number 类型,当不能转换为数值时,ToUnit32(this.length) 返回 0. 对于标准浏览器,上面已经将 slice 的原理解释清楚了。但是恼人的 ie, 总是给我们添乱子: 复制代码 代码如下: var slice = Array.prototype.slice; slice.call(); // => IE: Object expected. slice.call(document.childNodes); // => IE: JScript object expected. 以上代码,在 ie 里报错。可恨 IE 的 Trident 引擎不开源,那我们只有猜测了: 复制代码 代码如下: function ie_slice(start, end) { var len = ToUint32(this.length), result = []; if(__typeof__ this !== 'JScript Object') throw 'JScript object expected'; if(this === null) throw 'Oject expected'; for(var i = start; i < end; i++) { result.push(this[i]); } return result; } 至此,把猥琐的 ie 自圆其说完毕。 关于 slice, 还有一个话题:用 Array.prototype.slice 还是 [].slice ? 从理论上讲,[] 需要创建一个数组,性能上会比 Array.prototype 稍差。但实际上,这两者差不多,就如循环里用 i++ 还是 ++i 一样,纯属个人习惯。 最后一个话题,有关性能。对于数组的筛选来说,有一个牺牲色相的写法: 复制代码 代码如下: var ret = []; for(var i = start, j = 0; i < end; i++) { ret[j++] = arr[i]; } 用空间换时间。去掉 push, 对于大数组来说,性能提升还是比较明显的。 一大早写博,心情不是很好,得留个题目给大家: 复制代码 代码如下: var slice = Array.prototype.slice; alert(slice.call({0: 'foo', length: 'bar'})[0]); // ? alert(slice.call(NaN).length); // ? alert(slice.call({0: 'foo', length: '100'})[0]); // ?

  推荐阅读

  jQuery源码分析之Event事件分析

对于事件的操作无非是addEvent,fireEvent,removeEvent这三个事 件方法。一般lib都会对浏览器的提供的函数做一些扩展,解决兼容性内存泄漏等问题。第三个问题就是如何得到domReady的状态。   6.1 event的包裹   >>>详细阅读


本文标题:Array.prototype.slice 使用扩展

地址:http://www.17bianji.com/kaifa2/JS/26217.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)