javascript Array.prototype.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]); // ?

(0)

相关推荐

  • 深入了解javascript中的prototype与继承

    通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表.javascript创建对象时采用了写时复制的理念.只有构造器才具有prototype属性,原型链继承就是创建一个新的指针,指向构造器的prototype属性.prototype属性之所以特别,是因为javascript时读取属性时的遍历机制决定的.本质上它就是一个普通的指针. 构造器包括: 1.Object2.Function3.Array4.Date5.String 下面我们来举一些例子吧 复制代

  • javascript Prototype 对象扩展

    Javascript当然也不例外,可是关于对象的引用问题,你考虑过么?通常的做法是一系列对象共享类的方法,而不是为每个对象复制一份函数.下面看看为每个对象复制一份函数的做法. 复制代码 代码如下: var myobject=function(param1,param2) { this.name=param1; this.age=param2; this.showmsg=function() { alert("name:"+this.name+"\n"+"a

  • JavaScript中的prototype.bind()方法介绍

    以前,你可能会直接设置self=this或者that=this等等,这样做当然也能起作用,但是使用Function.prototype.bind()会更好,看上去也更专业.下面举个简单的例子: 复制代码 代码如下: var myObj = {    specialFunction: function () {    },    anotherSpecialFunction: function () {    },    getAsyncData: function (cb) {        c

  • 为JS扩展Array.prototype.indexOf引发的问题探讨及解决

    Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了.但是这个自定义的indexOf在对数组进行遍历的时候却出现了问题. Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了. 复制代码 代码如下

  • JavaScript为对象原型prototype添加属性的两种方式

    复制代码 代码如下: <script type="text/javascript"> <!-- /* 给原型 prototype 添加属性的两种方式 */ //方式一 var myObj = function(){ this.study = "JavaScript"; } myObj.prototype.hobby = function() { this.hobby = "See girl"; } var newObj = ne

  • js使用Array.prototype.sort()对数组对象排序的方法

    本文实例讲述了js使用Array.prototype.sort()对数组对象排序的方法.分享给大家供大家参考.具体分析如下: 在讲对数组对象进行排序时,我们先来简单的了解一下Array.prototype.sort().sort方法接受一个参数--Function,function会提供两个参数,分别是两个进行比较的元素,如果元素是String类型则通过Unicode code进行比较,如果是Number类型则比较值的大小.如果比较的函数中返回1则两个元素交换位置,0和-1不交换位置.先看一个例

  • javascript prototype的深度探索不是原型继承那么简单第1/3页

    1 什么是prototype JavaScript中对象的prototype属性,可以返回对象类型原型的引用.这是一个相当拗口的解释,要理解它,先要正确理解对象类型(Type)以及原型(prototype)的概念.         前面我们说,对象的类(Class)和对象实例(Instance)之间是一种"创建"关系,因此我们把"类"看作是对象特征的模型化,而对象看作是类特征的具体化,或者说,类(Class)是对象的一个类型(Type).例如,在前面的例子中,p1和

  • JavaScript中的原型prototype完全解析

    要理解JS中的prototype, 首先必须弄清楚以下几个概念    1. JS中所有的东西都是对象 2. JS中所有的东西都由Object衍生而来, 即所有东西原型链的终点指向Object.prototype // ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf&q

  • 判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解

    1.typeof(param) 返回param的类型(string) 这种方法是JS中的定义的全局方法,也是编译者们最常用的方法,优点就是使用简单.好记,缺点是不能很好的判断object.null.array.regexp和自定义对象. 示例代码: 复制代码 代码如下: var str='str';var arr=['1','2'];var num=1;var bool=true;var obj={name:'test'};var nullObj=null;var undefinedObj=un

  • 比较详细的javascript对象的property和prototype是什么一种关系

    ECMAScript可以识别两种类型的对象,一种叫做Native Object属于语言范畴;一种叫做Host Object,由运行环境提供例如document对象, Dom Node等 Native objects是一种松散的结构并且可以动态的增加属性(property),所有的属性都有一个名字和一个值,这个值可以是另一个对象的引用 或者是内建的数据类型(String, Number, Boolean, Null 或者 Undefined) 下面的这个简单的例子描述了一个javascript对象

随机推荐