javascript 为什么在给它分配其他东西时不通过引用传递这个对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9437981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why isn't this object being passed by reference when assigning something else to it?
提问by Dev555
I know that in JS, objects are passed by reference, for example:
我知道在JS中,对象是通过引用传递的,例如:
function test(obj) {
obj.name = 'new name';
}
var my_obj = { name: 'foo' };
test(my_obj);
alert(my_obj.name); // new name
But why doesn't the below work:
但为什么以下不起作用:
function test(obj) {
obj = {};
}
var my_obj = { name: 'foo' };
test(my_obj);
alert(my_obj.name); // foo
I have set the object to {}
(empty) but it still says foo
.
我已将对象设置为{}
(空),但它仍然显示foo
.
Can any one explain the logic behind this?
任何人都可以解释这背后的逻辑吗?
回答by Alexander Varwijk
If you are familiar with pointers, that's an analogy you can take. You're actually passing a pointer, so obj.someProperty
would dereference to that property and actually override that, while merely overriding obj
would kill off the pointer and not overwrite the object.
如果您熟悉指针,那么您可以进行类比。您实际上是在传递一个指针,因此obj.someProperty
会取消对该属性的引用并实际覆盖它,而仅覆盖obj
会杀死指针而不覆盖对象。
回答by Adam Rackis
Because JavaScript actually passes objects by pass-by-copy-reference.
因为 JavaScript 实际上是通过 pass-by- copy- reference 来传递对象的。
When you pass my_obj
into your test
function, a copyof a reference to that object is passed in. As a result, when you re-assign the object in test
, you're really only re-assigning a copy ofa reference to the original object; your original my_obj
remains un-changed.
当您传入my_obj
您的test
函数时,会传入对该对象的引用副本。因此,当您在 中重新分配对象时test
,实际上只是重新分配了对原始对象的引用副本;您的原始文件my_obj
保持不变。
回答by Quentin
Because you are overwriting the reference, not the object.
因为您正在覆盖引用,而不是对象。
// Create a new object and assign a reference to it
// to the variable my_obj
var my_obj = { name: 'foo' };
// Pass the reference to the test function
test(my_obj);
// Assign the reference to a variable called obj
// (since that is the first argument)
function test(obj) {
// Create a new (empty) object and assign a reference to it to obj
// This replaces the existing REFERENCE
obj = {};
}
// my_obj still has a reference to the original object,
// because my_obj wasn't overwritten
alert(my_obj.name); // foo
回答by Timo K?hk?nen
Javascript lacks support for passing by reference (although objects are passed by reference and the reference is maintained as long as it is not overwrited with assignment eg. using =
), but you can imitate ref
keyword of C# using the following technique:
Javascript 不支持通过引用传递(尽管对象是通过引用传递的,并且只要没有被赋值覆盖,引用就会被维护,例如 using =
),但是您可以ref
使用以下技术模仿C# 的关键字:
function test(obj) {
obj.Value = {};
//obj.Value = {name:"changed"};
}
var my_obj = { name: 'foo' };
(function ()
{
my_obj = {Value: my_obj};
var $return = test(my_obj);
my_obj = my_obj.Value;
return $return;
}).call(this);
alert(my_obj.name); // undefined, as expected
// In the question this returns "foo" because
// assignment causes dereference
Of course you can use globals and call function without arguments, in which case the references are not missed like this:
当然,您可以使用不带参数的全局变量和调用函数,在这种情况下,不会像这样错过引用:
var obj = { name: 'foo' };
function test() {
obj = {};
}
test();
alert(obj.name); // undefined
If you have all your code in closure, then things are simpler and above like globals doesn't pollute global namespace:
如果你的所有代码都在闭包中,那么事情就更简单了,就像 globals 不会污染全局命名空间一样:
(function(){
var obj = { name: 'foo' };
function test() {
obj = {};
}
test();
alert(obj.name); // undefined
}).call(this);
The above "globals inside closure" -technique is nice if you have to port to Javascript some C# code which has ref
arguments. Eg. The following C# code:
如果您必须将一些带有ref
参数的C# 代码移植到 Javascript,上面的“闭包内的全局变量”技术非常有用。例如。以下 C# 代码:
void MainLoop()
{
// ...
MyStruct pt1 = CreateMyStruct(1);
MyStruct pt2 = CreateMyStruct(2);
SwapPoints(ref pt1, ref pt2);
// ...
}
void SwapPoints(ref MyStruct pt1, ref MyStruct pt2)
{
MyStruct tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
could be ported to Javascript using something like:
可以使用以下内容移植到 Javascript:
(function(){
var pt1, pt2;
function CreateMyStruct(myvar)
{
return {"myvar":myvar}
}
function MainLoop()
{
// ...
pt1 = CreateMyStruct(1);
pt2 = CreateMyStruct(2);
console.log("ORIG:",pt1,pt2);
SwapPoints();
console.log("SWAPPED:",pt1,pt2);
// ...
}
function SwapPoints()
{
var tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
MainLoop();
}).call(this);
or if it's essential to use local variables and function arguments, then solution can be based on the first example of my answer like this:
或者如果必须使用局部变量和函数参数,那么解决方案可以基于我的答案的第一个示例,如下所示:
(function(){
function CreateMyStruct(myvar)
{
return {"myvar":myvar}
}
function MainLoop()
{
// ...
var pt1 = CreateMyStruct(1);
var pt2 = CreateMyStruct(2);
console.log("ORIG:",pt1,pt2);
(function ()
{
pt1 = {Value: pt1};
pt2 = {Value: pt2};
var $return = SwapPoints(pt1, pt2);
pt1 = pt1.Value;
pt2 = pt2.Value;
return $return;
}).call(this);
console.log("SWAPPED:",pt1,pt2);
// ...
}
function SwapPoints(pt1, pt2)
{
var tmp = pt1.Value;
pt1.Value = pt2.Value;
pt2.Value = tmp;
}
MainLoop();
}).call(this);
Really have to say that Javascript lacks much when it has not native ref
! The code would be much simpler.
真的不得不说,当它不是原生的时候,Javascript 缺乏很多ref
!代码会简单得多。