这可能是JS的细微差别,但如果我理解为什么会发生这种情况,那么我可能会想出一个解决方法。我需要能够访问对象" a"及其属性,在函数f1()中赋值。但是,尝试访问它们时,属性已消失。另外,为什么对象的prop1" b" = 1而不是100?
function Obj(){
var a = {};
var b = { prop1: 1, prop2: 2 };
var c = { prop1: 1, prop2: 2 };
var f1 = function(){
a = { prop1: 1, prop2: 2 };
// in real life this calls a function that returns an object
// a = someOtherFunctionThatReturnsAnObject();
};
var f2 = function(){
b = { prop1: 100, prop2: 200 };
};
var vm = {
f1:f1,
f2:f2,
a:a,
b:b,
c:c
};
return vm;
}
var obj = new Obj();
obj.f1();
obj.f2();
alert (obj.a.prop1); // undefined
alert (obj.b.prop1); // 1 * Why not 100? *
alert (obj.c.prop1); // 1
答案 0 :(得分:1)
有一个范围问题,我很难解释。对象vm被分配了b和c。 (和功能)。但是这些函数更新了局部变量var a,b,c。不是位于vm对象中的变量。
(就像我说的那样......很难解释)
但这就是它的工作原理..
function Obj(){
var vm = this; //Or var vm = {};
vm.a = {};
vm.b = { prop1: 1, prop2: 2 };
vm.c = { prop1: 1, prop2: 2 };
vm.f1 = function(){
vm.a = { prop1: 1, prop2: 2 };
// in real life this calls a function that returns an object
// a = someOtherFunctionThatReturnsAnObject();
};
vm.f2 = function(){
vm.b = { prop1: 100, prop2: 200 };
};
return vm;
}
var obj = new Obj();
obj.f1();
obj.f2();
答案 1 :(得分:0)
问题是你要覆盖方法f1和f2中的引用。
function Obj(){
var a = {};
var b = { prop1: 1, prop2: 2 };
var c = { prop1: 1, prop2: 2 };
var f1 = function(){
a = { prop1: 1, prop2: 2 }; /* <-- Overwriting the reference with a new object */
// in real life this calls a function that returns an object
// a = someOtherFunctionThatReturnsAnObject();
};
var f2 = function(){
b = { prop1: 100, prop2: 200 }; /* <-- Overwriting the reference with a new object */
};
var vm = {
f1:f1, /* <-- Passing reference */
f2:f2, /* <-- Passing reference */
a:a, /* <-- Passing reference */
b:b, /* <-- Passing reference */
c:c /* <-- Passing reference */
};
return vm;
}
var obj = new Obj();
obj.f1();
obj.f2();
alert (obj.a.prop1); // undefined
alert (obj.b.prop1); // 1 * Why not 100? *
alert (obj.c.prop1); // 1
要获得所需的行为,您需要更改引用的值。
var f2 = function(){
b.prop1 = 100; /* Changing the value on the referenced object */
b.prop2 = 200; /* Changing the value on the referenced object */
};
以及如何证明这一点。
您当前的解决方案,如果从方法f2返回对象b然后针对obj.b属性进行检查,它们将是不同的对象
var f2 = function(){
b = { prop1: 100, prop2: 200 }; /* <-- Overwriting the reference with a new object */
return b;
};
[...]
alert (obj.b === obj.f2()); // False, not the same object
如果改为改变obj.b对象的属性,它们将是相同的。
var f2 = function(){
b.prop1 = 100;
b.prop2 = 200;
return b;
};
[...]
alert (obj.b === obj.f2()); // True, the identical object
答案 2 :(得分:0)
如果我是从头开始写这个,我会像this
:
function Obj(){
this.a = {};
this.b = { prop1: 1, prop2: 2 };
this.c = { prop1: 1, prop2: 2 };
this.f1 = function(){
this.a = { prop1: 1, prop2: 2 };
};
this.f2 = function(){
this.b = { prop1: 100, prop2: 200 };
};
}
var obj = new Obj();
obj.f1();
obj.f2();
alert (obj.a.prop1); // 1
alert (obj.b.prop1); // 100
alert (obj.c.prop1); // 1
但是,由于您需要更改很多代码,因此您只需将this
添加到函数中的变量中:
function Obj(){
var a = {};
var b = { prop1: 1, prop2: 2 };
var c = { prop1: 1, prop2: 2 };
var f1 = function(){
this.a = { prop1: 1, prop2: 2 };
};
var f2 = function(){
this.b = { prop1: 100, prop2: 200 };
};
var vm = {
f1:f1,
f2:f2,
a:a,
b:b,
c:c
};
return vm;
}
var obj = new Obj();
obj.f1();
obj.f2();
alert (obj.a.prop1); // 1
alert (obj.b.prop1); // 100
alert (obj.c.prop1); // 1