javascript无法重新定义函数内部的全局对象

javascript can not redifine global object inside function

本文关键字:函数 内部 对象 全局 定义 新定义 javascript      更新时间:2023-09-26

这是代码,当函数更改对象的属性时,它可以工作,但重新定义对象,什么都没发生,为什么?我已经找到了一些答案,但我仍然不知道当对象作为函数中的参数时会发生什么。

var person = {name: "tom"};
function changeName(person) {
   person.name = "new tom";
   person = {};
}
changeName(person);
console.log(person);  //{name: "new tom"}

这与作用域有关。

函数有自己的范围,可以在中编辑,也可以从中编辑。

您的var person是针对window定义的。实际上它是window.perse={name:'tom'};

现在您进入您的功能。你创建了一个新的范围,一个空白的石板排序,说明你在哪里定义了一个参数人。

这意味着您不能再访问该对象中的全局对象person,因为您有一个以这种方式命名的作用域变量。

注意,htis变量只是一个"地址",它告诉函数在哪里找到实际对象Person。它被称为参考。

想象一下:你的电脑内存就像街上的房子

/-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'
[ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]
 1    2    3    4    5    6    7    8    9  

现在,在窗口对象中创建一个名为person的对象。我们在房子里简称它为p。一个人需要记忆才能生活,否则他会被卷走,所以他被放在的房子里

/-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'
[ ]  [ ]  [ ]  [p]  [ ]  [ ]  [ ]  [ ]  [ ]
 1    2    3    4    5    6    7    8    9  

然后你会收到一张纸条,上面写着:那个人住在4号房子里,当你需要和那个人一起做某事时,你可以看看纸条上的内容,去正确的房子和那个人做事情。(这听起来很不对,呵呵)

=|=
[|]
===

现在您进入您的功能。你把你的纸条传给函数,说"嘿,这个人住在4号。和他一起做事"

/-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'
[ ]  [ ]  [ ]  [p]  [ ]  [ ]  [ ]  [ ]  [ ]
 1    2    3    4    5    6    7    8    9  
                .
               =|=
               [|]
               ===

所以,你们的函数转到第四个房子,和那个最终有了新名字的人做一些事情。

但是你做

人={}

在那一刻,你正在积极地扔掉那张纸。你的程序完全忘记了这个人以前住在哪里!因此,它制作了一个新的人物对象,并将其放在一个新房子里,并将一张写有地址的纸交给可变人物。

/-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'
[ ]  [ ]  [ ]  [p]  [ ]  [p2]  [ ]  [ ]  [ ]
 1    2    3    4    5    6    7    8    9  
                          .
                         =|=
                         [|]
                         ===

并将继续与人2做事情,因为它完全忘记了人住在4号房子里,并且因为你扔掉了论文而无法检索到这些知识。(好吧,也许你可以用arguments数组做点什么)

如果你想彻底清除这个人,你需要清除所有对它的引用。在这一点上,只有一个对你的主要人物的引用。当你的函数存在时,第2个人将被清除,因为没有更多的引用。

但是人在窗口对象中仍然有一个引用。窗户上还放着一张纸,上面写着"嘿"。这个人住在4号房子里。

所以如果你在你的功能

window.person={}它创建了一个新人,为person对象分配了一个新房子,并在window对象中为person变量提供了一张带有地址的纸

然后,当垃圾收集器来的时候,它发现没有人有住在4号房子里的人的地址,并将其清理干净

/-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'  /-'
[ ]  [ ]  [ ]  [v]  [ ]  [p2]  [ ]  [ ]  [ ]
 1    2    3    v    5    6    7    8    9  
             '  v  /
              |_p__|-_
               o    o

实际上,它确实重新定义了person对象,但仅在函数范围内。试试这个:

function changeName(person) {
   person.name = "new tom";
   person = {};
   console.log(person.name); // gives undefined as expected
}
changeName(person);
console.log(person.name); // 'gives new Tom'

changeName中的person变量不可用于函数外的代码,因此person确实被设置为{},但一旦我们在函数外引用person,我们就得到了原始的person对象。(记住,在将person变量设置为{}之前,我们更改了它的名称值)

这可能会让它变得更清楚:

var person1 = {name: "tom"};
function changeName(person) {
   person.name = "new tom";
   person = {};
}
changeName(person1);
console.log(person);  //ERROR