2013-03-10 68 views
1

標題確實令人困惑,我找不到更好的標題。獲取對持有作爲構造函數的屬性的對象的引用

假設我有:

var A = function(){ 
    this.pa = { x: 1 }; 
}; 

A.prototype.B = function(){ 
    this.pb = /* a reference to { x: 1 } */; 
}; 

var a = new A(); 
var b = new a.B(); 
console.log (b.pb.x); //should print 1 
a.pa.x = 2; 
console.log (b.pb.x); //should print 2 

我想在pb保存到pa對象的引用。可能嗎?

+1

'新aB'不會創建新實例之間的關係'A.prototype.B'和'a'。構造函數調用與方法調用非常不同,因爲它們不會接收對方法目標的引用。 – 2013-03-10 19:55:53

+0

這就是爲什麼我問。任何黑客得到「a」的參考? – 2013-03-10 20:05:32

+0

你可以讓'b'返回一個綁定curry的getter屬性。 – 2013-03-10 22:31:17

回答

0

好吧,這不是正是我想要的,但它是非常接近:

var A = function (pa){ 
    this.pa = pa; 
}; 

A.prototype.B = function (a){ 
    if (this instanceof A.prototype.B){ 
     if (!a) throw "error"; 
     this.pb = a.pa; 
     return; 
    } 
    return new A.prototype.B (this); 
}; 

var a = new A ({ x: 1 }); 
var b = a.B(); 
console.log (b.pb.x); //1 
a.pa.x = 2; 
console.log (b.pb.x); //2 

new a.B() //throws "error" 
+0

如果您將「新A」分配給「a」以外的任何內容,則這不起作用。 – Bergi 2013-03-10 21:18:44

+0

您能否詳細說明評論?我不明白:) – 2013-03-10 23:26:18

+0

對不起,我忽略了'a'是構造函數的參數,並且傳入了一些東西。 – Bergi 2013-03-11 15:45:10

0
var A = function(){ 
    this.pa = { x: 1 }; 
}; 

A.prototype.B = function (a){ 

    this.pb = a.pa; 
}; 
var a = new A(); 

var b = new a.B(a); 
console.log(b.pb.x); //should print 1 
a.pa.x = 2; 
console.log(b.pb.x); 
+0

如果您將「新A」分配給「a」以外的任何內容,則這不起作用。 – Bergi 2013-03-10 21:19:20

+0

對不起,如果我不理解你,但你可以解釋你的意思是什麼,如果你將新的A賦予a以外的任何東西,這將不起作用。因爲儘管你的解決方案更加優雅,你的B是不是仍然綁定到A的特定實例? – Rohit 2013-03-10 22:06:22

+0

噢,對不起,我完全忽略了'a'是你的'B'構造函數的一個參數;我曾假設你試圖訪問全局的'a'變量。 – Bergi 2013-03-11 15:42:51

1

函數used as a constructor只有到新的實例的引用,從它的原型繼承。

要使它保持原來的A實例的引用,你就需要把B構造函數在閉包:

function A() { 
    var that = this; 
    this.pa = { x: 1 }; 

    this.B = function() { 
     this.pb = that.pa; 
    }; 
}; 

var a = new A(); 
var b = new a.B(); 
console.log (b.pb.x); // does print 1 
a.pa.x = 2; 
console.log (b.pb.x); // does print 2 

然而,這創造了新的B構造的缺點(其自己的原型對象)爲每個單個A實例。更好的方式是像

function A() { 
    this.pa = { x: 1 }; 
} 
A.B = function() { 
    this.pb = null; 
}; 
A.prototype.makeB = function() { 
    var b = new A.B(); 
    b.pb = this.pa; 
    return b; 
}; 
// you can modify the common A.B.prototype as well 

var a = new A(); 
var b = a.makeB(); 
console.log (b.pb.x); // does print 1 
a.pa.x = 2; 
console.log (b.pb.x); // does print 2 

然而,這樣你只有一個原型,但不同的構造函數,我們可以混用兩種形式:

function A() { 
    var that = this; 
    this.pa = { x: 1 }; 

    this.B = function() { 
     this.pb = that.pa; 
    }; 
    this.B.prototype = A.Bproto; 
} 
A.Bproto = { 
    … 
}; 
+0

我不能使用第二個選項,因爲'B'方法被稱爲'create() '。實際上,'B'的實際名稱是'User',所以我不能用一個名爲'makeUser()','createUser()','newUser()'或'newUserInstance()'的方法來實例化用戶。這是一個設計問題 – 2013-03-10 23:20:42

+0

第一個選項實際上是我想要實現的,但我必須在'A'構造函數內創建'B'的原型函數。每當新A被稱爲'B'的新原型被創建。我可以使用這個解決方案,因爲它是有效的,可行的,但它是無用的,並把我帶回到過去,在我開始學習JavaScript和做這樣醜陋的事情早年。 – 2013-03-10 23:25:00

相關問題