array.map()
应该很容易实现 defined in ECMA-262 ,它接受一个函数,这个函数将由 3 个参数调用:元素值、索引、数组。
但是对于稀疏数组呢?显然我们不想从索引 0 迭代到 100,000,如果只有索引 0、1、2 和 100,000 有一个元素,否则从索引 3 到 99,999 是稀疏的。我可以考虑使用 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;
};
(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;
}
我假设 Object.keys 以数字顺序返回数组的键,我认为这是实现定义的。如果没有,您可以对它们进行排序。
关于javascript - 如何为稀疏数组实现 Javascript ECMA 5 的 array.map()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12811254/