Javascript对象在赋值后丢失属性

时间:2015-02-20 18:38:46

标签: javascript properties module

这可能是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

3 个答案:

答案 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