Javascript 向生命传递对象
我正在生成一个函数,并使用IIFE将其推送到数组中,如下所示:Javascript 向生命传递对象,javascript,closures,Javascript,Closures,我正在生成一个函数,并使用IIFE将其推送到数组中,如下所示: var arr = []; var k; for(var i=0;i<3;i++) { k = {"val" : i}; arr.push( (function(j) { return function() { console.log(j) }; }(k)) ) } console.log(arr[0](), arr
var arr = [];
var k;
for(var i=0;i<3;i++) {
k = {"val" : i};
arr.push(
(function(j) {
return function() {
console.log(j)
};
}(k))
)
}
console.log(arr[0](), arr[1](), arr[2]());
但是,我正在传递
k
,这是使用I
生成的对象。由于对象是通过引用传递的,所以我希望它使用值2,2,2
记录对象,但我得到的是0,1,2
。当通过值传递基元类型时,这不是通常的行为吗,为什么即使在我使用按引用传递(对象)时也会发生同样的事情 与k={“val”:i}
您正在创建一个新对象并将其分配给k
。请尝试使用var k={}
和k.val=i
。您得到的是0、1、2而不是3、3、3,因为k
的值被传递到函数中。k
的值是对象引用。JavaScript没有任何形式的传递引用,因此函数接收的不是对k
变量的引用,而是调用函数时k
中的对象引用的副本。在下一步中,创建一个新对象并将其放入k
变量中,但这对最内层函数关闭的j
变量的值没有任何影响
将对象引用想象成一个大数组(内存)的索引,告诉JavaScript引擎对象所在的位置k
包含该引用(数字),而不是实际对象。将引用复制到第二个变量(或将其传递到函数)时,对象的引用有两个副本,但只有一个对象
让我们简化一下,并使用一些ASCII艺术::-)
在这些代码行之后,下面是我们的内存(省略一些不必要的细节):
……我们有:
k:REF#123−−−−−−+
| +−−−−−−−−−−−−−−−−+
+−−−−>| Object@REF#123 |
| +−−−−−−−−−−−−−−−−+
j:REF#123−−−−−−+ | val: 0 |
+−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#4 |
| +−−−−−−−−−−−−−−+
| | val: 1 |
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+
+−>| Object@REF#2 | |
| +−−−−−−−−−−−−−−+ |
| | val: 0 | |
| +−−−−−−−−−−−−−−+ |
| |
| |
+−−−−−−−−−−+ | |
arr−−−>| Array | | |
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ | |
| 0: REF#1 |−−−>| Function@REF#1 | | |
| 1: REF#3 |−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
+−−−−−−−−−−+ | | [[Environment]] |−−>| Environment | | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
| | j: REF#2 |−+ |
| +−−−−−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−+ |
+−>| Function@REF#3 | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| [[Environment]] |−−>| Environment | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| j: REF#4 |−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
现在我们有了一个新对象,具有不同的引用:
+−−−−−−−−−−−−−−−−+
k:REF#462−−−−−−−−−−−>| Object@REF#462 |
+−−−−−−−−−−−−−−−−+
| val: 1 |
+−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−+
j:REF#123−−−−−−−−−−−>| Object@REF#123 |
+−−−−−−−−−−−−−−−−+
| val: 0 |
+−−−−−−−−−−−−−−−−++
在中间调用每个IFIE创建一个执行环境,并附带一个环境记录。从概念上讲,环境记录是一个包含变量和参数值等函数调用的对象(您不能在代码中访问此对象,它是规范中的一个概念,不一定是JavaScript引擎中的文字)。该环境记录包含j
参数。IIFE创建了一个新函数,它会记住对创建它的环境的引用(使用名为[[environment]]的内部插槽),并返回该引用;函数被推送到数组中
下面是第一次循环后内存的样子(再次省略一些不必要的细节):
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#2 |
| +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ | | val: 0 |
arr−−−>| Array | | +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ |
| 0: REF#1 |−−−−>| Function@REF#1 | |
| 1: REF#3 |−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
+−−−−−−−−−−+ | | [[Environment]] |−>| Environment | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| | j: REF#2 |−+
| +−−−−−−−−−−−−−+
| +−−−−−−−−−−−−−−−−−+
+−>| Function@REF#3 |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
| [[Environment]] |−>| Environment |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
| j: REF#4 |
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
K−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#2 |
| +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ | | 瓦尔:0|
啊−−−>| 数组| |+−−−−−−−−−−−−−−+
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ |
|0:REF#1|−−−−>| Function@REF#1 | |
|1:参考文献3|−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
+−−−−−−−−−−+ | | [[环境]]|−>| 环境||
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
|| j:参考文献2|−+
| +−−−−−−−−−−−−−+
| +−−−−−−−−−−−−−−−−−+
+−>| Function@REF#3 |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
|[[环境]]|−>| 环境|
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
|j:参考文献4|
+−−−−−−−−−−−−−+
在第二个循环之后,您有:
k:REF#123−−−−−−+
| +−−−−−−−−−−−−−−−−+
+−−−−>| Object@REF#123 |
| +−−−−−−−−−−−−−−−−+
j:REF#123−−−−−−+ | val: 0 |
+−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#4 |
| +−−−−−−−−−−−−−−+
| | val: 1 |
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+
+−>| Object@REF#2 | |
| +−−−−−−−−−−−−−−+ |
| | val: 0 | |
| +−−−−−−−−−−−−−−+ |
| |
| |
+−−−−−−−−−−+ | |
arr−−−>| Array | | |
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ | |
| 0: REF#1 |−−−>| Function@REF#1 | | |
| 1: REF#3 |−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
+−−−−−−−−−−+ | | [[Environment]] |−−>| Environment | | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
| | j: REF#2 |−+ |
| +−−−−−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−+ |
+−>| Function@REF#3 | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| [[Environment]] |−−>| Environment | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| j: REF#4 |−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
K−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#4 |
| +−−−−−−−−−−−−−−+
|| val:1|
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+
+−>| Object@REF#2 | |
| +−−−−−−−−−−−−−−+ |
|| val:0 ||
| +−−−−−−−−−−−−−−+ |
| |
| |
+−−−−−−−−?
+−−−−−−−−−−−−−−−−+
k:REF#462−−−−−−−−−−−>| Object@REF#462 |
+−−−−−−−−−−−−−−−−+
| val: 1 |
+−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−+
j:REF#123−−−−−−−−−−−>| Object@REF#123 |
+−−−−−−−−−−−−−−−−+
| val: 0 |
+−−−−−−−−−−−−−−−−++
var arr = [];
var k;
for(var i=0;i<3;i++) {
k = {"val" : i};
arr.push(
(function(j) {
return function() {
console.log(j)
};
}(k))
)
}
console.log(arr[0](), arr[1](), arr[2]());
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#2 |
| +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ | | val: 0 |
arr−−−>| Array | | +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ |
| 0: REF#1 |−−−−>| Function@REF#1 | |
| 1: REF#3 |−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
+−−−−−−−−−−+ | | [[Environment]] |−>| Environment | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| | j: REF#2 |−+
| +−−−−−−−−−−−−−+
| +−−−−−−−−−−−−−−−−−+
+−>| Function@REF#3 |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
| [[Environment]] |−>| Environment |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
| j: REF#4 |
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#4 |
| +−−−−−−−−−−−−−−+
| | val: 1 |
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+
+−>| Object@REF#2 | |
| +−−−−−−−−−−−−−−+ |
| | val: 0 | |
| +−−−−−−−−−−−−−−+ |
| |
| |
+−−−−−−−−−−+ | |
arr−−−>| Array | | |
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ | |
| 0: REF#1 |−−−>| Function@REF#1 | | |
| 1: REF#3 |−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
+−−−−−−−−−−+ | | [[Environment]] |−−>| Environment | | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
| | j: REF#2 |−+ |
| +−−−−−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−+ |
+−>| Function@REF#3 | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| [[Environment]] |−−>| Environment | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| j: REF#4 |−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−+
k−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| Object@REF#6 |
| +−−−−−−−−−−−−−−+
| | val: 2 |
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+
+−>| Object@REF#4 | |
| +−−−−−−−−−−−−−−+ |
| | val: 1 | |
+−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−+ |
+−>| Object@REF#2 | | |
| +−−−−−−−−−−−−−−+ | |
| | val: 0 | | |
| +−−−−−−−−−−−−−−+ | |
| | |
| | |
+−−−−−−−−−−+ | | |
arr−−−>| Array | | | |
+−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ | | |
| 0: REF#1 |−−−−−−>| Function@REF#1 | | | |
| 1: REF#3 |−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | | |
| 2: REF#5 |−−+ | | [[Environment]] |−−>| Environment | | | |
+−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | | |
| | | j: REF#2 |−+ | |
| | +−−−−−−−−−−−−−+ | |
| | +−−−−−−−−−−−−−−−−−+ | |
| +−>| Function@REF#3 | | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
| | [[Environment]] |−−>| Environment | | |
| +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ | |
| | j: REF#4 |−−−−−−−−−−−−−−−−−−−−−+ |
| +−−−−−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−+ |
+−−−>| Function@REF#5 | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| [[Environment]] |−−>| Environment | |
+−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+ |
| j: REF#6 |−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+
var arr = [];
var k;
for(var i = 0; i < 3; i++) {
arr.push(function() {
console.log(i)
})
}
for(var i = 0; i < 3; i++) {
(function(j) {
arr.push(function() {
console.log(j)
})
})(i)
}
arr[0]()
arr[1]()
arr[2]()
arr[3]()
arr[4]()
arr[5]()