Joh*_*ino 89 javascript arrays foreach dictionary prototype
我在map和foreach中看到的唯一区别map是返回一个数组而forEach不是.但是,我甚至不理解方法的最后一行forEach" func.call(scope, this[i], i, this);".例如,是不是" this"和" scope"指的是同一个对象而不是this[i]并且i指的是循环中的当前值?
我在另一篇文章中注意到有人说" forEach当你想根据列表的每个元素做某事时使用.例如,你可能会在页面上添加内容.基本上,它非常适合你想要的"副作用".我不知道副作用是什么意思.
Array.prototype.map = function(fnc) {
var a = new Array(this.length);
for (var i = 0; i < this.length; i++) {
a[i] = fnc(this[i]);
}
return a;
}
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
for (var i = 0, l = this.length; i < l; i++) {
func.call(scope, this[i], i, this);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这些方法在javascript中是否有任何实际用途(因为我们不更新数据库),除了操纵这样的数字:
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
Run Code Online (Sandbox Code Playgroud)
谢谢你的回复.
Ken*_*ler 93
您map和forEach示例之间的本质区别在于forEach对原始数组元素进行操作,而map显式返回新数组作为结果.
随着forEach你正在采取一些行动 - 并且可选地改变 - 原始数组中的每个元素.该forEach方法运行您为每个元素提供的函数,但不返回任何内容(undefined).另一方面,map遍历数组,将函数应用于每个元素,并将结果作为新数组发出.
"副作用" forEach是原始数组正在改变."无副作用" map意味着,在惯用法中,原始数组元素不会改变; 新数组是原始数组中每个元素的一对一映射 - 映射变换是您提供的函数.
没有涉及数据库这一事实并不意味着您不必对数据结构进行操作,毕竟数据结构是任何语言编程的本质之一.至于你的上一个问题,你的数组不仅可以包含数字,还可以包含对象,字符串,函数等.
nra*_*itz 65
这两种方法之间的主要区别是概念和风格:您可以使用forEach,当你想要做的事,以或与数组中的每个元素(做"和"什么是你引用的"副作用"的意思后,我想) ,而您map在想要复制和转换数组的每个元素时使用(而不更改原始元素).
因为无论map和forEach调用每个项目的功能在阵列中,且功能被用户定义的,几乎没有什么可以与一个而不是与其他做.虽然很丑,但是可以使用它map来就地修改数组和/或使用数组元素做一些事情:
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.map(function(el) {
el.val++; // modify element in-place
alert(el.val); // do something with each element
});
// a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]
Run Code Online (Sandbox Code Playgroud)
但是你的意图更清晰,更明显forEach:
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.forEach(function(el) {
el.val++;
alert(el.val);
});
Run Code Online (Sandbox Code Playgroud)
特别是如果像现实世界中的情况那样,el是一个有用的人类可读变量:
cats.forEach(function(cat) {
cat.meow(); // nicer than cats[x].meow()
});
Run Code Online (Sandbox Code Playgroud)
以同样的方式,您可以轻松地使用forEach新的数组:
var a = [1,2,3],
b = [];
a.forEach(function(el) {
b.push(el+1);
});
// b is now [2,3,4], a is unchanged
Run Code Online (Sandbox Code Playgroud)
但使用起来更清洁map:
var a = [1,2,3],
b = a.map(function(el) {
return el+1;
});
Run Code Online (Sandbox Code Playgroud)
还要注意,因为map创建一个新数组,当你需要的只是迭代时,它可能会产生至少一些性能/内存命中,特别是对于大型数组 - 请参阅http://jsperf.com/map-foreach
至于为什么你想要使用这些函数,只要你需要在javascript中进行数组操作,它们就会很有用,这些(即使我们只是在浏览器环境中讨论javascript)经常是,几乎在任何时候您正在访问一个您未在代码中手动写下的数组.您可能正在处理页面上的DOM元素数组,或从AJAX请求中提取的数据,或者用户在表单中输入的数据.我遇到的一个常见示例是从外部API中提取数据,您可能希望map将数据转换为所需的格式,然后使用forEach迭代新数组以便将其显示给用户.
Jac*_*ang 16
投票的答案(来自Ken Redler)具有误导性.
甲副作用在计算机科学意味着一个功能/方法的一个属性改变全局状态[维基].从狭义上讲,这也可能包括从全球国家而不是从争论中读取.在命令式或OO编程中,大多数时候都会出现副作用.你可能在没有意识到的情况下使用它.
forEach和之间的显着差异map是map分配内存并存储返回值,同时forEach抛弃它.有关更多信息,请参阅emca规范.
至于人们说forEach当你想要副作用时使用的原因是返回值forEach总是如此undefined.如果它没有副作用(不改变全局状态),那么该函数只是浪费cpu时间.优化编译器将消除此代码块并将其替换为最终值(undefined).
顺便说一下,应该注意JavaScript对副作用没有限制.你仍然可以修改里面的原始数组map.
var a = [1,2,3]; //original
var b = a.map( function(x,i){a[i] = 2*x; return x+1} );
console.log("modified=%j\nnew array=%j",a,b);
// output:
// modified=[2,4,6]
// new array=[2,3,4]
Run Code Online (Sandbox Code Playgroud)
以下是基于官方的描述Array.prototype.map().
没有什么是forEach()可以做到这一点map()做不到.也就是说,map()是一个严格的超集的forEach().
虽然map()通常用于创建新数组,但它也可用于更改当前数组.以下示例说明了这一点:
var a = [0, 1, 2, 3, 4], mapped = null;
mapped = a.map(function (x) { a[x] = x*x*x; return x*x; });
console.log(mapped); // logs [0, 1, 4, 9, 16] As expected, these are squares.
console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,a方便地设置a[i] === i为i < a.length.即便如此,它也证明了它的强大功能map(),特别是它能够改变调用它的阵列.
注1:
官方描述暗示map()甚至可能改变调用它的数组的长度!但是,我看不到(很好)这样做的理由.
注2:
虽然map()map是超集forEach(),但是forEach()仍然应该在需要更改给定数组的地方使用.这使你的意图清晰.
希望这有帮助.