2011-01-22 15 views
7

在Javascript中,我想限定具有內部(或嵌套的)類的類。在內部類中,我希望能夠訪問父實例。我怎樣纔能有效地做到這一點?的Javascript,內部類,以及如何訪問父範圍有效地

一些代碼會顯示我的意思。假設我定義一個類,MyType1,這暴露了幾個屬性和一個功能,SayHello

(function(){ 
    MyType1 = function(name){ 
     this.TypeName = "MyType1"; 
     this.Name = name; 
    }; 

    MyType1.prototype.SayHello = function() { 
     say(this.Name + " says hello..."); 
    }; 
})(); 

好了,現在,從那裏開始,我想添加一個「內部類」到MyType1,所以我加入了一些新的代碼,以便它看起來像這樣:

(function(){ 
    MyType1 = function(name){ 
     this.TypeName = "MyType1"; 
     this.Name = name; 
     var parentName = name; 
     this.Child = function(name) { 
      this.Description = parentName + "'s child, " + name; 
     }; 

     this.Child.prototype.Introduce = function() { 
      say(this.Description + ", greets you..."); 
     }; 
    }; 

    MyType1.prototype.SayHello = function() { 
     say(this.Name + " says hello..."); 
    }; 
})(); 

現在,我可以使用這些類是這樣的:

var x = new MyType1("Victor"); 
x.SayHello(); 

var c = new x.Child("Elizabeth"); 
c.Introduce(); 

,所有的作品。但是它爲MyType1的每個實例定義了一個新的Child函數(或類型,如果您喜歡)。我想要做的就是訪問父類的範圍,而不是訴諸低效率。 事情是這樣的:

(function(){ 
    MyType2 = function(name){ 
     this.TypeName = "MyType2"; 
     this.Name = name; 
     this.Prop1 = 1872; 
     var parentName = name; 
    }; 

    MyType2.prototype.SayHello = function() { 
     say(this.Name + " says hello..."); 
    }; 

    var c1 = function(name) { 
     this.Description = parentName + "'s child, " + name; 
     //    ^^ no go! ^^ 
    }; 

    c1.prototype.Introduce = function() { 
     say(this.Description + ", greets you..."); 
    }; 

    MyType2.prototype.Child = c1; 

})(); 

但是,這是行不通的。當然,parentName var不在範圍之內。

是否有子實例的有效方式(在構造函數中,或在任何類的函數)來訪問父(MyType2)實例?


我知道我可以定義子類是一個獨立的,非嵌套類,然後在構造函數爲,只是通過父實例。但是這會創建對父實例的N個引用,每個子實例都有一個引用。這似乎是我想避免的低效率。

感謝您的任何提示。


編輯 - 我希望孩子能夠訪問父實例的原因,就是母公司持有的對象,它是相當昂貴的創造 - 有點像一個數據庫連接 - 我想孩子能夠利用那個東西。

+3

呃,還有更多濫用Javascript引入「OOP」廢話。這種語言沒有類:如果你想要它們,使用它的東西! – 2011-01-22 15:23:51

+1

您可能會覺得這很有用:http://blog.niftysnippets.org/2009/09/simple-efficient-supercalls-in.html它是一組幫助函數(及其解釋),它提供了一種簡單但有效的方法創建通過原型繼承創建的「類」的「子類」。看起來你正在做相當的手動,所以它可以爲您節省一些麻煩。 – 2011-01-22 15:24:07

回答

4

它可能會幫助你,如果你用JavaScript打交道時包含「類型」,「類」等概念做了。在javascript中,與「類型」,「類」,「函數」,「實例」或「對象」沒有任何區別 - 它一直是「對象」。由於每個「類型」是一個「對象」並且是可變的,因此您不會獲得通過重用單一類型定義而從Java或C++中獲得的強類型效率增益。將JavaScript中的「new」運算符想象爲「克隆定義並調用構造函數」之類的內容,之後實例的定義仍可以更改。

因此,請遵循您的第一個工作示例:通過採取不同的行動,您不會獲得任何收益。

1

我能想到的唯一的辦法就是在父對象傳遞給孩子的構造函數:

MyType2.Child = function (parent, name) { 
    this.parent = parent; 
    this.name = name; 
    this.Description = this.parent.name + "'s child, " + name; 
}; 

並與實例吧:

var x = new MyType2("Victor"); 

var c = new MyType2.Child(x, "Elizabeth"); 

我的理由是,它更有意義該Child構造是MyType2「靜態」的屬性,在你的例子實例化對象x代替,因爲我們是在談論類型在這裏,這是在S橫跨所有MyType2的實例。

2

這是我幾個小時後,來到了起來:

var Parent = function() { 
    this.name = "Parent"; 

    this.Child = Child; 
    this.Child.prototype.parent = this; 
} 

var Child = function() { 

} 

var parent = new Parent(); 
var child = new parent.Child(); 

console.log(child.parent.name); 

這樣,只要你想,他們的童車 下,和每一個孩子實例將有機會獲得它,你可以實例許多家長的父實例 通過變量父母

0

我沒有測試過這一點,但你應該能夠使用JSON這個:

//code here 
var number = { 
    real : { 
     value : 0, //default value 
     rational : { 
      integer : { 
       isNegative : false, 
       value : 0 //default value 
      } 
     } 
    }, 
    imaginary : { 
     //code 
    } 
}; 

var number2 = Object.create(number.rational.integer.prototype); 

現在有可能與此的許多問題,功能或風格。但它是這裏發佈的其他方法的替代方案。

相關問題