我很抱歉,如果这是一个noob问题,我仍然是JS的新手,为什么不覆盖函数内的变量工作?
var o = {x: 1};
function foo(){
// Overwrite var `o` with a string
arguments[0] = "string";
}
foo(o);
console.log(o); // Why is `o` still an object and not the string `string`?
- 根据回复更新---
但为什么会这样呢?
// Define an array literal
var a = ["a", "b"];
// Execute whatever function is passed to manipulate the array
a.execFunc = function(func){
func(this) // Pass this array (object) to it
}
// Invoke `execFunc` function passing another function
a.execFunc(function(thisArray){
thisArray[0] = "c"; // Change first element to "c"
})
console.log(a); // => ["c", "b", execFunc: function]: IT WORKED! a → c
---更新#2 ----
很抱歉只是试着把我的想法包围在说什么 - 为什么然后这不起作用?它与上面基本相同吗?我正在修改原始数组,而不是arguments
对象,不是我吗?
// Define an array literal
var a = ["a", "b"];
// Execute whatever function is passed to manipulate the array
a.execFunc = function(func){
func(this[0]) // Pass the first element (object property) to it
}
// Invoke `execFunc` function passing another function
a.execFunc(function(firstElement){
console.log(firstElement = "c"); // Change first element to "c"
})
console.log(a); // => ["a", "b", execFunc: function]: first element is still `a`
答案 0 :(得分:3)
当您将对象作为参数传递给函数时,arguments
特殊对象将保存对实际对象的引用。当你这样做
arguments[0] = ...
您只是将元素设为0引用不同的对象,而不是更改o
。如果你试试这个
function foo() {
console.log(arguments);
arguments[0] = "string";
console.log(arguments);
}
输出
{ '0': { x: 1 } }
{ '0': 'string' }
如您所见,0
之前的元素指的是o
,并且已更改为string
。那就是它。
相反,试试这个
function foo() {
arguments[0].x = "string";
}
你会得到
{ x: 'string' }
当您打印o
时,因为arguments[0]
引用o
而.x
引用o
中的属性。所以你实际上正在改变o
。这称为变异对象。
以同样的方式,thisArray
引用您的实际数组对象,当您将元素更改为0时,实际上您正在更改作为参数传递的实际数组。这就是为什么thisArray
中的突变也反映在你的实际数组对象中。
答案 1 :(得分:1)
如果您在功能中更改了对象的' 属性,则javascript会找到该引用并进行更改。
如果您只是更改了对象的'值,则javascript会将其视为局部变量,而不是获取引用并进行修改。
在第一个中,你没有改变o的属性,所以它只是覆盖了参数[0],并没有将任何东西设置为变量o。你需要在函数中返回新值并设置为o,应该是这样的:
var o = {x: 1};
function foo(){
// Overwrite var `o` with a string
arguments[0] = "string";
return arguments[0];
}
o = foo(o);
console.log(o);
//will be "string"
或者
var o = {x: 1};
function foo(){
// Overwrite var `o` with a string
o = "string";
}
foo();
console.log(o);
//will be "string"
你的第二个是这样的:
var a = ["a","b"];
function foo(){
// Overwrite var `o` with a string
arguments[0][0] = "c";
}
foo(a)
console.log(a)
//will be ["c", "b"]
您倾向于更改数组a的属性。所以它指的是一个数组。但是在第一个示例中,您只需更改其值,以便它不会引用o对象。
您的更新#2
您只需更改"值"一个[0]。所以它不会引用数组a。与此类似:
var a = ["a", "b"];
function foo(){
arguments[0] = "c";
}
foo(a[0]);
console.log(a);
//will be ["a", "b"]