如何访问另一个原型对象的变量

时间:2015-10-29 02:18:22

标签: javascript

具有数组和getter / setter的类。

var MyObject = (function MyObject() {
    this.arr = [];

    MyObject.prototype.addArr =  function(i) {
        this.arr.push(i);
    };
    MyObject.prototype.getArr =  function() {
        return this.arr;
    };
});

另一个对象尝试访问MyObject数组。

var AnotherObject = (function AnotherObject() {
    AnotherObject.prototype.addToMyObject =  function(i, MyObject) {
        MyObject.addArr(i); // here's the problem!
    };
    AnotherObject.prototype.getArr =  function(MyObject) {
        return MyObject.getArr();
    };
});

现在测试。

var a = new MyObject();    
a.addArr(1);
a.addArr(2);
a.addArr(3);

// works good.
console.log(a.getArr().pop()); // 3
console.log(a.getArr()); // [1,2]

var b = new AnotherObject();
b.addToMyObject(4);
b.addToMyObject(5);
b.addToMyObject(6);

console.log(b.getArr().shift()); // error!
console.log(b.getArr());

它说AnotherObject.addToMyObject()是错误的。 'addArr'未在addToMyObject()内定义或为空。

纠正我如何访问另一个Object的变量

http://jsfiddle.net/amhk9o2a/2/

3 个答案:

答案 0 :(得分:2)

AnotherObject的方法期望MyObject作为参数传递。所以它应该是:

b.addToMyObject(4, a);
b.addToMyObject(5, a);
b.addToMyObject(6, a);
console.log(b.getArr(a).shift());
console.log(b.getArr(a));

由于您没有传递此参数,因此MyObject参数变量设置为undefined,因此您调用了undefined.addArr(i)undefined.getArr()

答案 1 :(得分:1)

以下是构造函数的更好示例:

function MyObject(){
  this.arr = [];
  this.addArr = function(i){
    this.arr.push(i);
  }
  this.getArr = function(){
    return this.arr;
  }
}
function AnotherObject(){
}
AnotherObject.prototype = MyObject.prototype;
// now AnotherObject has MyObject prototype

答案 2 :(得分:1)

我通过代码做了一些更改。为了更容易理解我标记的A,B和C部分。

  • 修复了MyObject的构造函数定义,因此每次创建时都不会销毁原型并重新创建原型它的一个实例
  • B 修复了AnotherObject的构造函数定义,因此每次创建时都不会销毁原型并重新创建原型它的一个实例
  • B 教会了我们选择目标对象的新方法
  • C 构造的实例,AnotherObject实例我使用新方法定位MyObject实例
// --- A ---
function MyObject() {
    this.arr = [];
}
MyObject.prototype.addArr = function (i) {
    this.arr.push(i);
};
MyObject.prototype.getArr = function () {
    return this.arr;
};

// --- B ---
function AnotherObject() {
}
AnotherObject.prototype.setTarget = function (myObject) { // extra bit
    this.target = myObject;
};
AnotherObject.prototype.addToMyObject = function (i) {
    this.target.addArr(i); // this now points to a new place
};
AnotherObject.prototype.getArr = function(MyObject) {
    return this.target.getArr(); // this now points to a new place
};

// --- C ---
var a = new MyObject(),
    b = new AnotherObject();
b.setTarget(a); // Enemy sighted, assigning it as the target!!!!
b.addToMyObject('foo');
b.getArr(); // ["foo"]
// notice this also means
a.getArr(); // ["foo"]

使用 IIFE

编写您尝试过的构造函数的先前样式看起来好像是以下样式
var MyObject = (function () {
    function MyObject() {
        this.arr = [];
    }
    MyObject.prototype.addArr = function (i) {
        this.arr.push(i);
    };
    MyObject.prototype.getArr = function () {
        return this.arr;
    };
    return MyObject;
}());

这是一种非常有效的方法来保持命名空间的清晰,但阅读起来更复杂。如果您是构建者或 IIFE 的新手,我建议您首先相互独立地学习它们。