I apologize if this is a noob question, I'm still kind of new to JS, Why doesn't overwriting a variable work inside a function?
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`?
-- Update based on responses ---
But why does this then work?
// 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
--- Update #2 ----
Sorry just trying to wrap my mind around what is being said - why then DOESN'T this work? Isn't it basically the same as above? I'm modifying the original array just like above, not an arguments
object, aren't I?
// 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`
When you are passing an object as an argument to a function, the arguments
special object will hold a reference to the actual object. When you do
arguments[0] = ...
you are simply making the element at 0 refer a different object, you are not changing o
. You can understand this better, if you try this
function foo() {
console.log(arguments);
arguments[0] = "string";
console.log(arguments);
}
The output will be
{ '0': { x: 1 } }
{ '0': 'string' }
as you can see, the element at 0
earlier was referring to o
and that has been changed to string
. That's it.
Instead, try this
function foo() {
arguments[0].x = "string";
}
you will get
{ x: 'string' }
when you print o
, because, arguments[0]
refers to o
and the .x
refers to a property in o
. So you are actually changing o
. This is called mutating an object.
In the same way, thisArray
refers to your actual array object and when you change the element at 0, you are actually changing your actual array passed as the argument. That is why mutations in thisArray
reflects in your actual array object as well.
If you change the object's 'property' in function, javascript will find the reference and change it.
If you just change object's 'value' , javascript will treat it as a local variable instead get the reference and modify it.
In first one, you didn't change the property of o, so it just overwrite argument[0], and didn't set anything to variable o. You need to return new value in function and set to o, should be like this:
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"
Or
var o = {x: 1};
function foo(){
// Overwrite var `o` with a string
o = "string";
}
foo();
console.log(o);
//will be "string"
Your second one is like this:
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"]
You tend to change property of array a. So it refer to a array. But in your first sample, you just change its value so it will not refer to o object.
Your update #2
You just change the "value" of a[0]. So it will not refer to array a. Similar as this:
var a = ["a", "b"];
function foo(){
arguments[0] = "c";
}
foo(a[0]);
console.log(a);
//will be ["a", "b"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.