请教个问题,关于JS作用域的,看了网上的也不是很懂。
发布于 4 年前 作者 heguangda 2127 次浏览 来自 问答

V{77V{BPQCQV5M{N6{075XM.png 如图,我把 var temp = {};写在for循环外面之后 alldata里面的数全部变成了for循环后一个temp,但是写在里面就是我想要的结果没什么呀 ![E7}KSXHF5APU%}BQ}3QQOD.png 想问一下js 的array.push()不是异步回调来的把?

7 回复

有一张图片显示不了 是把var temp ={} 写在for 循环外面的

写在里面每次循环都是一个新对象,写在外面每次循环都是对同一个对象进行操作
这个和作用域也没什么关系,应该说是传值和传引用区别的知识点

var temp ={} 相当于 var temp = new Object(),放外面只创建了一次,放里面就是每次创建一个新的。

值传递和引用传递的区别,你放入alldata的只是一个引用而已

问题的关键不在于声明是在for循环外还是内。关键在于你在 for循环内有个动作。temp = {} var arr = []; var obj = {a: 1}; arr.push(obj); console.log(arr);
// 以上打印的arr应该是 [{a: 1}] // 继续以下操作 obj.a = 2; console.log(arr); // 那么打印的应该是 [{a: 2}] // 继续如下操作 var obj1 = obj; obj = {a: 3} console.log(arr); // 那么打印的应该是 [{a: 2}] // 继续下面操作 obj1.a = 4 console.log(arr); // 那么打印的应该是 [{a: 4}] push的时候,记录的是obj这个变量指向的堆栈地址。 obj始终指向那个地址,你只要修改了它的内容,比如把其中a属性改为2,那么push的那个数组也变了。 但是你把obj指向了另一个新对象。那么push的那个数组已经不受obj的影响了。这里obj1还指向那个地址,所以obj1的修改,可以反馈到push的那个数组里。 push是个函数,函数的参数是按值传递还是引用?每次调用push,函数内部都是copy一把钥匙,它也指向那个堆栈地址。

首先,明确一下,题主要搞清什么是值类型和引用类型的值 https://segmentfault.com/a/1190000006752076

第一种情况:temp 放在for内部,每次执行就会新开一个内存空间存放数据,然后push当前的数据引用。 没有问题 第二种情况:temp 放在for外部,每次执行,修改属性值 对象temp都是指向的同一个内存地址,你push 1w遍 也是全部指向同一个value temp。 所以是有问题的。

你需要先理解JS中值类型和引用类型的区别: 值类型:值类型是直接存储的原始值,例如a[0] = 1, 此时a[0]存的是1。看下图

引用类型:引用类型存的是它的地址(可以想象成对象的门牌号),它的原始值是存在堆内存中的,例如var temp = {};a[0] = temp, 此时a[0]存的是temp的地址。看下图

你再来看这个问题可能就容易很多了。

var temp = {} 放在for循环外面,此时for循环内共用一个对象, 你给temp赋值的时候,并没有改变数组中所存的地址。

var temp = {} 放在for循环里面,此时,每执行一次for循环,都会新建一个对象。

回到顶部