局部变量和参数之间的区别
function addLinks() {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function (num) {
return function() {
alert(num);
};
}(i);
}}
为每个链接创建闭包;每个封闭都参考它创建的范围。由于参数num
已在每个循环上更新,因此在第一个链接上的click
上应该提示4
。不是吗?局部变量和参数之间的区别
根本不是,每个函数调用得到num
变量的新副本,以便第一个链接应该提醒0
如果你真的想拥有所有的回调共享相同的变量...然后只是有它们共享相同的变量(包装“民”的东西正是要避免这个问题,让回调是独立的):
//now all the inner closures use the same "i" variable
//since the variable gets mutated by the for loop
//all links are going to print "5" after the loop ends.
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function() {
alert(i);
};
}
BTW,这只是发生,因为不像在其他语言,JS没有块循环索引的范围。因为如果你做了
var i;
while(i < 5){
//...
i++
}
你应该提到JS有一个功能范围,而'i'“活在”函数中,而不是循环中(也不是每次循环)。 – Joseph 2013-04-07 16:07:21
号
for循环的行为而由于你混淆两件事情:
函数的参数是函数的局部(用大“除非”,保存为2号)
它们旨在以您选择的任何名称为函数的作用域别名一个对象(包括数组/函数)或值。
目标是允许您将参数重命名为任何您想要的内容,以使内部代码变得有意义,而不管您从外部代码传入的参数是什么。
这与范围无关。JS中的变量通过引用传递(如果它们是对象),如果它们是标量,则通过值传递。
传递i
到一个新的封闭的整点是,值i
被作为参数传递,而不是参考到i
,这是发生了什么,如果你不要” t包括关闭。
如果你要传递一个对象,该对象是什么了就可以了i
(obj.i += 1
),然后再次关闭与否,每个功能将指向的i
相同的值,因为他们” d都与同一个对象共享相同的参考。
对象由参考通过,标量由值通过。
尽管技术上有字符串和数字对象,但只要您没有对它们进行任何面向对象的操作,它们就会直接转换为标量值。
var i = 3,
say_i = function() { console.log(i); };
与
var i = 3,
say_i = (function (val) { return function() { console.log(val); }(i));
第一个给出了一个参考到i
。
当say_i
运行时,它实时查看i
的值,并将其吐出到控制台中。
第二个已通过一个值到返回的函数的外范围,别名为名称val
。
由于数字是按值传递的,而不是通过引用,所以val
将永远等于相同的东西,除非从里面改变。
你也可以做到这一点相同的结果,如果你犯了一个功能一次,循环外:
var add_log = function (el, val) { el.onclick = function() { console.log(val); }; },
i = 0,
el;
for (; i < ........) {
el = ....
add_log(el, i);
}
i
正在按值传递的,因此,所有的元素将在其范围表中的不同val
因此,每个元素都会记录一个不同的数字。
参数num从不更新,它是每个调用的新变量。 – bfavaretto 2013-04-07 16:06:25