Array.prototype.slice 使用扩展

 更新时间:2010年06月09日 18:08:55   作者:  
slice 可以用来获取数组片段,它返回新数组,不会修改原数组。
除了正常用法,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]); // ?

相关文章

  • javascript级联下拉列表实例代码(自写)

    javascript级联下拉列表实例代码(自写)

    javascript下拉菜单想必大家在浏览网页的时候都会看到吧,已不是那么陌生了,本文介绍使用javascript实现级联下拉列表实例,感兴趣的朋友可以参考下哈,希望对你有所帮助
    2013-05-05
  • 基于JS实现十种酷炫的网页特效

    基于JS实现十种酷炫的网页特效

    之前喜欢收集能美化网页的代码,比如给网页加个背景啦,给鼠标加个特效啦,来来回回也收集到了一些“使用简单”,“效果爆炸”的页面,快来学习一下吧
    2022-04-04
  • javascript inneHTML的地雷

    javascript inneHTML的地雷

    大家都喜欢用innerHTML添加内容,但是innerHTML这东西在两大阵营中有许多不同。
    2010-02-02
  • 小试JavaScript多线程

    小试JavaScript多线程

    这两天一直在弄ajax,用多了才发现了ajax 的cache问题,请求了好多次,得到了确是相同的结果,经常我想在请求的同时去做一些其它的事情,我在想javascript里有没有办法用多线程,经过在网上查找找到了结果。
    2008-11-11
  • 理解javascript正则表达式

    理解javascript正则表达式

    这篇文章主要为大家详细介绍了javascript正则表达式,由浅入深的帮助大家学习正则表达式,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 阻止移动端touchmove与scroll事件冲突技巧

    阻止移动端touchmove与scroll事件冲突技巧

    这篇文章主要为大家介绍了阻止移动端touchmove与scroll事件冲突技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 纯javascript制作日历控件

    纯javascript制作日历控件

    本文给大家分享的是使用纯javascript实现的日历控件的代码,笔者也是第一次写控件,摸索着前行,
    2015-07-07
  • JavaScript数值数组排序示例分享

    JavaScript数值数组排序示例分享

    在Javascript中我们已知有两个可以直接用来进行数组排序的方法reverse()和sort()。其中reverse()是按照反向对于数组进行排序的,而sort()是按照正向进行排序的。
    2014-05-05
  • 在HTML中嵌入JS代码的3种方式总结

    在HTML中嵌入JS代码的3种方式总结

    现在的前端JavaScript可以说是异常火爆,即使并不准备向前端发展,但是对前端的一些基础知识还是必须有所了解的,先这篇文章主要给大家介绍了关于在HTML中嵌入JS代码的3种方式,需要的朋友可以参考下
    2022-11-11
  • 详解JavaScript如何实现一个简易的Promise对象

    详解JavaScript如何实现一个简易的Promise对象

    Promise对象的作用将异步操作以同步操作的流程表达出来,避免层层嵌套的回调函数,而且Promise提供了统一的接口,使得控制异步操作更加容易。本文介绍了如何实现一个简单的Promise对象,需要的可以参考一下
    2022-11-11

最新评论