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

时间:2015-04-09 07:14:44

标签: javascript

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

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

2 个答案:

答案 0 :(得分:2)

这与范围界定有关。

一个函数有自己的编辑范围。

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

现在您输入您的功能。您可以创建一个新的范围,一个空白的平板排序,以说明您在何处定义参数人。

这意味着您无法再访问该对象中的全局对象人员,因为您有一个以这种方式命名的范围变量。

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

想象一下:你的电脑记忆就像街上的房子

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

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

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

然后你得到一张纸条说:人住在4号门,当你需要和你在滑倒的人做某事时,去正确的房子和人做事。(这听起来很错误HEH)

=|=
[|]
===

现在输入你的功能。你把你的论文传递给了“嘿,生活在4号的人”这个函数。

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

所以你的功能会转到第四号,然后以一个以新名字命名的人来完成。

但是你做了

person = {}

那一刻,你正在积极地扔掉这张纸。你的程序完全忘记了人们过去住的地方! 因此,它会创建一个新的人物对象并将其放入一个新的房子,并将一张纸张保存给变量人。

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

并将继续与person2做事,因为它完全忘记了人住在四号楼,并且没有检索知识的范围,因为你扔掉了论文。(好吧,也许你可以用参数数组做一些事情)

如果你想完全清理人,你需要清理所有对它的引用。此时,您的主要人物只有一个参考。 当你的functino存在时,人2将被清理,因为没有更多的参考。

但是人仍然在窗口对象中有一个引用。窗户仍然拿着一张纸说嘿。这个人住在4号门。

所以,如果你做了你的功能

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

然后当垃圾收集器到来时,看到没有人有住在4号门的人的地址并清理它

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

答案 1 :(得分:0)

实际上,它确实重新定义了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变量设置为{}之前更改了它的名称值)

这可能会更清楚:

var person1 = {name: "tom"};

function changeName(person) {
   person.name = "new tom";
   person = {};
}

changeName(person1);

console.log(person);  //ERROR