2009-02-11 120 views
2

函數Obj1(param) this.test1 = param || 1; }JavaScript調用另一個謎題函數

function Obj2(param, par) 
{ 
    this.test2 = param; 
    this.ob = Obj1; 
    this.ob(par); 
} 

現在爲什麼如果我這樣做:

alert(new Obj2(44,55).test1); 

輸出爲55?如果我沒有 鏈接通過原型鏈,怎麼能'查看'test1 Obj2 istance?

感謝

回答

2

如果我沒有通過原型鏈鏈接兩者,如何'查看'test1和Obj2 istance?

方法沒有綁定在JavaScript中。當您編寫以下任一項時:

o.method(x); 
o['method'](x); 

將'o'的值賦給方法內的'this'。但!如果分離,從物體的功能,並直接調用它:

m= o.method; 
m(x); 

參考,以「O」丟失,並調用該方法,就好像它是一個普通的老功能,具有全局對象「本次」。與之相似,如果移動功能到另一個對象,有稱之爲:

o2.method= o.method; 
o2.method(x); 

那麼「這個」將是「O2」,而不是「O」。對於具有一流功能的語言而言,這是非常奇怪的行爲,並且非常直觀,但這是您的JavaScript。

如果您希望能夠使用綁定方法,則需要創建自己的方法,通常使用閉包。請參閱ECMAScript 3.1中提出的「Function.bind」方法或許多框架中的類似實現。

所以無論如何:

this.ob = Obj1; 
this.ob(par); 

這正在OBJ1作爲一個函數和變成上「這」的方法,它是一個OBJ2實例。所以當Obj1被調用時,它自己的'this'也是Obj2,這就是它寫入它的參數'this'。同樣可以寫得更簡單明瞭:

Obj1.call(this, par); 

你是否故意這樣做?它可以用作一種繼承,在你自己的類上調用另一個類的構造函數,並且這個方法在一些JS面向對象教程中講授。然而,這並不是一個很好的方式,因爲你最終會得到同一個屬性的多個副本;使用原型可以節省您的時間,並按照預期在超類過濾器上進行屬性更新。

7

那麼它目前還不清楚你什麼,但出現這種情況的原因是因爲這裏:

this.ob = Obj1; 

您添加OBJ1方法OBJ2的對象實例,當你使用在這裏:

this.ob(par); 

的情況下「本」的方法中OBJ1是OBJ 2實例。所以那個實例現在有一個test1成員。

真的跟繼承沒有關係,但它有點像混合。記住,JS函數是第一類對象。

1

什麼this裏面的函數是指取決於你如何調用函數。如果你把它叫做sender.fn(),那麼this就是sender(你的情況)。如果您將其作爲fn(),那麼this是全局對象。

5

讓我們來看看Obj1爲函數。所以,當你做

function Obj2(param, par) 
{ 
    this.test2 = param; 
    this.ob = Obj1; 
    this.ob(par); 
} 

你的代碼變得等同於下面的代碼:

function Obj2(param, par) 
{ 
    this.test2 = param; 
    this.ob = function (param) { this.test1 = param || 1; } 
    this.ob(par); 
}