Array.prototype.slice 使用扩展


Posted in Javascript onJune 09, 2010

除了正常用法,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中几种排序算法的简单实现
Jul 29 Javascript
初步使用Node连接Mysql数据库
Mar 03 Javascript
JavaScript中创建对象的模式汇总
Apr 19 Javascript
Bootstrap学习笔记之css样式设计(2)
Jun 07 Javascript
关于JavaScript 原型链的一点个人理解
Jul 31 Javascript
AngularJS实现单独作用域内的数据操作
Sep 05 Javascript
JavaScript实现时钟滴答声效果
Jan 29 Javascript
vue-cli3环境变量与分环境打包的方法示例
Feb 18 Javascript
vue实现二级导航栏效果
Oct 19 Javascript
js实现的在本地预览图片功能示例
Nov 09 Javascript
js实现轮播图效果 纯js实现图片自动切换
Aug 09 Javascript
Vue2.0 ES6语法降级ES5的操作
Oct 30 Javascript
Confirmer JQuery确认对话框组件
Jun 09 #Javascript
Jquery CheckBox全选方法代码附js checkbox全选反选代码
Jun 09 #Javascript
JavaScript 原型与继承说明
Jun 09 #Javascript
JavaScript 构造函数 面相对象学习必备知识
Jun 09 #Javascript
JS 图片缩放效果代码
Jun 09 #Javascript
JQuery优缺点分析说明
Jun 09 #Javascript
web页面数据展示新想法(json)
Jun 08 #Javascript
You might like
PHP 实现多服务器共享 SESSION 数据
2009/08/15 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
PHP 多任务秒级定时器的实现方法
2018/05/13 PHP
实例讲解php将字符串输出到HTML
2019/01/27 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
用javascript控制iframe滚动的代码
2007/04/10 Javascript
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
js控制table合并具体实现
2014/02/20 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
js停止冒泡和阻止浏览器默认行为的简单方法
2016/05/15 Javascript
最丑的时钟效果!js canvas时钟制作方法
2016/08/15 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
Vue2.0学习之详解Vue 组件及父子组件通信
2017/12/12 Javascript
在create-react-app中使用css modules的示例代码
2018/07/31 Javascript
[03:42]2014DOTA2国际邀请赛 第三日比赛排位扑朔迷离
2014/07/12 DOTA
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
python+unittest+requests实现接口自动化的方法
2018/11/29 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
Python对象与引用的介绍
2019/01/24 Python
python分别打包出32位和64位应用程序
2020/02/18 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
python实现批量命名照片
2020/06/18 Python
详解前端HTML5几种存储方式的总结
2016/12/27 HTML / CSS
高性能钓鱼服装:Huk Gear
2019/02/20 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
秋季运动会演讲稿
2014/09/16 职场文书
个人债务授权委托书
2014/10/17 职场文书
买卖合同协议书范本
2014/10/18 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
运动员代表致辞
2015/07/29 职场文书
2019个人年度目标制定攻略!
2019/07/12 职场文书
redis实现共同好友的思路详解
2021/05/26 Redis
一篇文章带你复习java知识点
2021/06/28 Java/Android
SpringCloud项目如何解决log4j2漏洞
2022/04/10 Java/Android