为什么这个对象不是通过引用传递给它的东西呢?
我知道在JS中,对象是通过引用传递的,例如:
function test(obj) { obj.name = 'new name'; } var my_obj = { name: 'foo' }; test(my_obj); alert(my_obj.name); // new name
但为什么不下面的工作:
function test(obj) { obj = {}; } var my_obj = { name: 'foo' }; test(my_obj); alert(my_obj.name); // foo
我已经设置对象{}
(空),但它仍然说foo
。
任何人都可以解释这背后的逻辑吗?
如果你对指针很熟悉,那么你可以这样做。 实际上,你传递的是一个指针,所以obj.someProperty
会解引用那个属性,而实际上会覆盖这个属性,而只是重写obj
会杀掉指针而不覆盖对象。
因为JavaScript实际上是通过pass-by- copy -reference来传递对象的。
当你将my_obj
传递给你的test
函数时,会传入一个对该对象的引用的副本 。因此,当你在test
重新分配对象时,你实际上只是重新分配一个引用的副本给原始对象; 你原来的my_obj
保持不变。
因为你覆盖了引用,而不是对象。
// 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
Javascript缺乏对引用传递的支持(尽pipe对象是通过引用传递的,并且引用被保持,只要它没有被赋值使用,例如using =
),但是可以使用以下技术来模拟C#的ref
关键字:
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
当然,你可以使用全局variables和不带参数的调用函数,在这种情况下引用不会像这样丢失:
var obj = { name: 'foo' }; function test() { obj = {}; } test(); alert(obj.name); // undefined
如果你closures了所有的代码,那么事情就简单了,像全局variables一样不会污染全局名称空间:
(function(){ var obj = { name: 'foo' }; function test() { obj = {}; } test(); alert(obj.name); // undefined }).call(this);
上面的“闭包内的全局variables”技术是很好的,如果你必须移植到一些C#代码有ref
参数。 例如。 以下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; }
可以使用像这样的东西移植到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);
或者如果必须使用局部variables和函数参数,则解决scheme可以基于我的答案的第一个示例,如下所示:
(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);
真的不得不说,当它没有本地ref
Javascript缺乏多less! 代码会简单得多。