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]); // ?

相关文章

  • 解决layui追加或者动态修改的表单元素“没效果”的问题

    解决layui追加或者动态修改的表单元素“没效果”的问题

    今天小编就为大家分享一篇解决layui追加或者动态修改的表单元素“没效果”的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • Javascript实现时间倒计时效果

    Javascript实现时间倒计时效果

    这篇文章主要为大家详细介绍了Javascript实现时间倒计时效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • 微信小程序账号密码登入和传值的实现方法

    微信小程序账号密码登入和传值的实现方法

    传统的web开发实现登陆功能,一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录,下面这篇文章主要给大家介绍了关于微信小程序账号密码登入和传值的实现方法,需要的朋友可以参考下
    2022-04-04
  • JS实现文本比较差异的示例代码

    JS实现文本比较差异的示例代码

    内部系统上线了一个发版记录发版内容的功能,维护发版记录的同事提出一个可以展示前后文本差异的优化需求, 使的每次变更前可以确认新增了哪些,或者删除了哪些内容,所以本文给大家介绍了基于JS实现文本比较差异,需要的朋友可以参考下
    2023-12-12
  • JavaScript原始值与包装对象的详细介绍

    JavaScript原始值与包装对象的详细介绍

    这篇文章主要给大家介绍了关于JavaScript原始值与包装对象的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • JS中的BOM应用

    JS中的BOM应用

    我们曾经讲过JS由三部分组成,其中一个部分就是BOM,用于对浏览器进行操作。这篇文章我们主要来介绍BOM应用,感兴趣的朋友一起看看吧
    2018-02-02
  • javascript轮播图算法

    javascript轮播图算法

    这篇文章主要为大家详细介绍了javascript轮播图算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Axios设置token请求头的三种方式

    Axios设置token请求头的三种方式

    用户登录时,后端会返回一个token,并且保存到浏览器的localstorage中,可以根据localstorage中的token判断用户是否登录,所以当发送请求时,都要携带token给后端进行判断,本文给大家介绍了Axios设置token请求头的三种方式,需要的朋友可以参考下
    2024-02-02
  • JavaScript对象详解之对象属性的添加

    JavaScript对象详解之对象属性的添加

    这篇文章主要给大家介绍了关于JavaScript对象详解之js对象属性的添加的相关资料,在JavaScript中对象是通过键值对来存储数据的一种数据类型,可以通过直接给对象添加属性的方式来增加对象的属性,需要的朋友可以参考下
    2023-07-07
  • Javascript中的this绑定介绍

    Javascript中的this绑定介绍

    在Javascript里,函数被调用的时候,除了接受声明是定义的形式参数,每一个函数还接受两个附加的参数:this和arguments。
    2011-09-09

最新评论