2015-11-02 22 views
1

我正在定義一個Parent對象,並且我希望它具有一個具有自己的函數和私有變量的子成員對象。爲了封裝函數和變量,我給Parent原型添加了一個自動執行的匿名函數。從自我執行的匿名成員函數內部訪問父級原型範圍

這裏的代碼演示問題:

var Parent = function() { 
 
    this.memberVariable = 'hello world'; 
 
} 
 

 
Parent.prototype.doSomething = function() { 
 
    return this.childObject.doSomething(); 
 
}; 
 

 
Parent.prototype.childObject = function() { 
 
    // instead of being Parent, `this` is the Window object. What is the best way to fix this? 
 
    var that = this; 
 
    
 
    return { 
 
     doSomething: function() { 
 
      // undefined, but should be 'hello world' 
 
      return that.memberVariable; 
 
     } 
 
    } 
 
}(); 
 

 
var parent = new Parent(); 
 
console.log(parent.doSomething());

一個解決方法我是通過在父範圍內給孩子的功能,但是這似乎不可思議,而且好像有一定是一個更好的解決方案:

var Parent = function() { 
 
    this.memberVariable = 'hello world'; 
 
} 
 

 
Parent.prototype.doSomething = function() { 
 
    // we pass in `this` 
 
    return this.childObject.doSomething(this); 
 
}; 
 

 
Parent.prototype.childObject = function() { 
 
    return { 
 
     doSomething: function(that) { 
 
      return that.memberVariable; 
 
     } 
 
    } 
 
}(); 
 

 
var parent = new Parent(); 
 
console.log(parent.doSomething());

有沒有更好的方法來實現這個目標?

+0

你應該看看模塊/顯露的模塊模式... http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript – AdamJeffers

+0

你不能有一個IEFE創建原型方法,並期望得到裏面有一個動態的'this'。 – Bergi

+0

[組織原型javascript,同時保持對象引用和繼承](http://stackoverflow.com/q/15884096/1048572) – Bergi

回答

4

初始化childObjectParent構造函數中。否則,Parent的所有實例將共享相同的childObject。這可能不是你想要的。

function Parent() { 
    this.childObject = new Child(this); // or something like makeChild(parent), or just an object literal. 
} 

function Child(parent) { 
    this.parent = parent; 
} 
+0

這並沒有發生在我身上,因爲Parent是一個單身人士,所以我沒有考慮'childObject'定義的範圍。這是一個更清潔的解決方案。謝謝! – brismuth

0

使用callapply

Parent.prototype.doSomething = function() { 
    return this.childObject.doSomething.call(this); 
}; 

或者你可以使用bind

Parent.prototype.childObject = function() { 
    return { 
     doSomething: (function() { 
      // undefined, but should be 'hello world' 
      return this.memberVariable; 
     }).bind(this) 
    } 
}(); 
+0

'.call()'也是我嘗試過的東西之一,但我不'不是非常喜歡它,要麼是因爲它必須被附加到對'childObject'的每一次調用中。這是做這件事的最好方法嗎? – brismuth

+0

你可以使用'bind' ...將更新。 –