Array.prototype.slice 使用扩展_javascript技巧
程序员文章站
2022-03-09 17:05:56
...
除了正常用法,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 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 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 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]); // ?
名词解释: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 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 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 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]); // ?
推荐阅读
-
使用VSCode调试javascript/typescript的一个技巧
-
Jquery中扩展方法教程extend使用技巧
-
JavaScript ES6中的简写语法总结与使用技巧
-
9种使用Chrome Firefox 自带调试工具调试javascript技巧
-
javaScript 逻辑运算符使用技巧整理
-
ES6/JavaScript使用技巧分享
-
Powershell小技巧之使用Jint引擎在PowerShell中执行Javascript函数
-
Powershell小技巧之使用Get-ChildItem得到指定扩展名文件
-
JavaScript小技巧:!!的使用
-
JavaScript开发中JQuery each()嵌套使用技巧