有人可以解释这两个javascript片段之间的区别:
var orange = { prop: "i am simple fruit"};
console.log(orange.prop); //output: "i am simple fruit"
function go(orange) {
orange.prop = "Now i have been changed by the function";
};
go(orange);
console.log(orange.prop); // output: "Now i have been changed by the function"
。
在上面的块中,go
函数显然更改了外部范围中的orange
变量/对象
。
var apple = "i am simple apple";
console.log(apple); // output "i am simple apple"
function goApple(apple) {
apple = "Now i have been changed by the function";
};
goApple(apple);
console.log(apple); // output "i am simple apple"
在此块中,外部apple
变量未更改
我遗漏了一些基本而明显的东西,或者javascript在变量类型之间有不同的范围规则?
答案 0 :(得分:1)
这一行
function goApple(apple) {
定义一个大致定义局部变量的函数参数。这是您正在更改的本地变量,而不是外部变量。
当你对orange
做同样的事情时,你也有一个局部变量但是你没有改变局部变量的值,只改变了这个值的属性(因此碰巧是同一个橙色对象)而不是在外部范围内。)
答案 1 :(得分:1)
区别在于你传递的参数的类型。
typeof apple //"string"
typeof orange //"object"
传递字符串文字时,您传递不可变数据,并且它由值传递,因此无法更改。
编辑:也就是说,window.apple
指向的数据无法更改。更改window.apple
的唯一方法是将其指向一些新数据。 window.apple = "something new";
答案 2 :(得分:0)
Javascript将始终按值传递函数参数。 在第一种情况下,您将访问通过引用传递的对象的属性。当apple传递给函数时,该引用被复制到橙色。因此,两者都指向内存中的相同对象
答案 3 :(得分:0)
如果函数参数与外部变量的名称不同,那么您的问题可能会更清楚一些。实际上,您使用apple
和orange
作为全局变量和参数变量,它们在函数内部影响外部全局变量。
var apple = "i am simple apple";
console.log(apple); // output "i am simple apple"
function goApple(appleArg) {
appleArg = "Now i have been changed by the function";
};
goApple(apple);
console.log(apple); // output "i am simple apple"
在此,您正在更改 值appleArg
所指的。这对外部变量apple
所指的值没有影响。
在orange
示例中,您修改对象本身,而不是任何引用该对象的变量。
var orange = { prop: "i am simple fruit"};
console.log(orange.prop); //output: "i am simple fruit"
function go(orangeArg) {
orangeArg.prop = "Now i have been changed by the function";
};
go(orange);
console.log(orange.prop); // output: "Now i have been changed by the function"
此处,orange
和orangeArg
引用相同的值,并且它们永远不会更改它们引用的值。 (在apple
示例中,appleArg
变量更改为引用与apple
不同的值。)但是,值本身会发生变化(因此单个两个变量引用变量的值,但两个变量都不会更改它引用的值。)
使用字符串,您无法修改值本身,因为基元是不可变的。使用对象,您可以修改值的属性。考虑第三种情况,我们改变变量引用的值:
var mango = { prop: "i am simple fruit"};
console.log(mango.prop); //output: "i am simple fruit"
function go(mangoArg) {
mangoArg = { prop: "Now i have been changed by the function" };
};
go(mango);
console.log(mango.prop); // output: "i am simple fruit"
此处,我们更改mangoArg
的方式与我们修改appleArg
的方式相同。我们将mangoArg
引用了全新值,而不是修改mango
引用的对象。