它应该很容易实现array.map(),它在ECMA-262中定义,它接受一个函数,这个函数将由3个参数调用:元素值,索引,数组.
但是对于稀疏数组呢?显然,如果只有索引0,1,2和100,000具有一个元素,并且从索引3到99,999稀疏,我们不希望从索引0迭代到100,000.我可以考虑使用arr.slice(0)或arr.concat()克隆数组,然后输入替换值,但是如果我们不使用slice或者concat,还有其他方法吗?
我想出的解决方案slice()是:
Array.prototype.collect = Array.prototype.collect || function(fn) {
var result = this.slice(0);
for (var i in this) {
if (this.hasOwnProperty(i))
result[i] = fn(this[i], i, this); // 3 arguments according to ECMA specs
}
return result;
};
Run Code Online (Sandbox Code Playgroud)
(collect用于试用代码,因为这是map某种语言的另一个名称)
这应该很容易,但有一些特殊之处。
回调函数可以修改相关数组。它添加或删除的任何元素都不会被访问。所以看来我们应该使用类似 Object.keys 的东西来确定要访问哪些元素。
此外,结果被定义为一个新数组,就像由数组构造函数“创建”并获取旧数组的长度一样,因此我们也可以使用该构造函数来创建它。
这是考虑到这些因素的实现,但可能遗漏了一些其他微妙之处:
function map(callbackfn, thisArg) {
var keys = Object.keys(this),
result = new Array(this.length);
keys.forEach(function(key) {
if (key >= 0 && this.hasOwnProperty(key)) {
result[key] = callbackfn.call(thisArg, this[key], key, this);
}
}, this);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我假设 Object.keys 按数字顺序返回数组的键,我认为这是实现定义的。如果没有,您可以对它们进行排序。
| 归档时间: |
|
| 查看次数: |
1593 次 |
| 最近记录: |