范围 JavaScript 中变量和对象之间的差异
Scoping Differences between variables and objects in javascript
有人可以解释一下这两个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 对变量类型有不同的范围规则?
区别在于您传递的参数的类型。
typeof apple //"string"
typeof orange //"object"
传递字符串文本时,您传递的是不可变数据,并且它是按值传递的,因此它无法更改。
编辑:也就是说,window.apple
指向的数据无法更改。更改window.apple
的唯一方法是将其指向一些新数据。 window.apple = "something new";
此行
function goApple(apple) {
定义一个函数参数,该参数大致定义一个局部变量。这是您要更改的局部变量,而不是外部变量。
当你对orange
执行相同的操作时,你也有一个局部变量,但你没有改变局部变量的值,只是这个值的一个属性(因此它恰好是与外部作用域相同的橙色对象(。
Javascript 将始终按值传递函数参数。在第一种情况下,您正在访问通过引用传递的对象的属性。当 apple 传递给函数时,该引用将复制到橙色。因此,两者都引用内存中的同一对象
如果您的函数参数与外部变量的名称不同,您的问题可能会更清晰一些。实际上,您将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"
在这里,我们以与修改appleArg
相同的方式更改了mangoArg
。我们mangoArg
引用一个全新的值,而不是修改 mango
引用的对象。
- 全局变量和全局对象的属性之间有什么区别吗
- JavaScript中的函数和对象之间没有区别吗?
- 在控制器和数据对象之间同步数据
- Javascript-defineProperty和直接在对象上定义函数之间的区别
- XMLHttpRequest对象的open()和send()方法之间有什么区别
- Firefox插件SDK:在侧边栏和主脚本之间通信对象
- 如何将json文件中的数据提取到对象数组中,并在两个控制器之间共享
- Angular 2,在没有直接关系的两个组件之间共享一个对象
- 尝试在一个对象的值和一个对象数组之间进行匹配
- 在angularJS中使用模态窗口时,在控制器之间共享对象数组
- 快递之间的区别.路由器() vs 多个 express() 对象
- 节点模块对象范围:在所有函数之间共享一个对象
- 在不同数据选项之间循环迭代对象
- 在 JavaScript 中的对象内分配柯里函数时,这和 self 之间有什么区别吗?
- 不同对象之间的递归,并将它们唯一地组合在一起,不重复
- 两个对象之间的Javascript原型
- 什么's对象文字中带引号和不带引号的键之间的区别
- 只有一些带undercore.js的字段在对象数组之间求交集和等于
- 用户如何获取两个时间戳之间的对象
- 在window.onload之前/之后创建对象之间的区别