我为一些任务写了一个简单的地图实现.然后,出于好奇,我又写了两篇.我喜欢map1,但代码有点难以阅读.如果有人感兴趣,我会很感激简单的代码审查.
哪一个更好?你知道在javascript中实现这个的其他方法吗?
var map = function(arr, func) {
var newarr = [];
for (var i = 0; i < arr.length; i++) {
newarr[i] = func(arr[i]);
}
return newarr;
};
var map1 = function(arr, func) {
if (arr.length === 0) return [];
return [func(arr[0])].concat(funcmap(arr.slice(1), func));
};
var map2 = function(arr, func) {
var iter = function(result, i) {
if (i === arr.length) return result;
result.push(func(arr[i]));
return iter(result, i+1);
};
return iter([], 0);
};
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑
我一般都在考虑这种功能.
例如,现在我将使用它来迭代这样:
map(['class1', 'class2', 'class3'], function(cls) {
el.removeClass(cls);
});
Run Code Online (Sandbox Code Playgroud)
要么
ids = map(elements, extract_id);
/* elements is a collection of html elements,
extract_id is a func that extracts id from innerHTML */
Run Code Online (Sandbox Code Playgroud)
那么在Firefox和SpiderMonkey上本地使用的地图实现怎么样,我认为它非常直接:
if (!Array.prototype.map) {
Array.prototype.map = function(fun /*, thisp*/) {
var len = this.length >>> 0; // make sure length is a positive number
if (typeof fun != "function") // make sure the first argument is a function
throw new TypeError();
var res = new Array(len); // initialize the resulting array
var thisp = arguments[1]; // an optional 'context' argument
for (var i = 0; i < len; i++) {
if (i in this)
res[i] = fun.call(thisp, this[i], i, this); // fill the resulting array
}
return res;
};
}
Run Code Online (Sandbox Code Playgroud)
如果您不想扩展Array.prototype,请将其声明为普通函数表达式.
我认为这取决于当 func 可能更改数组时您希望 map 做什么。我倾向于在简单性和样本长度方面犯一次错误。
您始终可以指定输出大小,如下所示
var map = function(arr, func) {
var n = arr.length & 0x7fffffff; // Make sure n is a non-neg integer
var newarr = new Array(n); // Preallocate array size
var USELESS = {};
for (var i = 0; i < n; ++i) {
newarr[i] = func.call(USELESS, arr[i]);
}
return newarr;
};
Run Code Online (Sandbox Code Playgroud)
我使用 func.call() 形式而不仅仅是 func(...) ,因为我不喜欢在不指定“this”是什么的情况下调用用户提供的代码,但是 YMMV。