在javascript中确定变量和对象之间的差异

时间:2014-11-10 14:29:34

标签: javascript angularjs

有人可以解释这两个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在变量类型之间有不同的范围规则?

4 个答案:

答案 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)

如果函数参数与外部变量的名称不同,那么您的问题可能会更清楚一些。实际上,您使用appleorange作为全局变量和参数变量,它们在函数内部影响外部全局变量。

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"

此处,orangeorangeArg引用相同的值,并且它们永远不会更改它们引用的值。 (在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引用的对象。