2017-10-19 65 views
0
function DoIHavePrototype() 
{ 
    var a = 10; 
} 

CheckIt = new DoIHavePrototype(); 

DoIHavePrototype.prototype.GetFnName = function() 
{ 
    return "DoIHavePrototype" 
} 

alert(CheckIt.GetFnName()) 

在上面的代碼中,我觀察到原型是函數的內置屬性,我們可以使用該屬性將屬性/方法附加到函數中。是否有可能將方法追加到沒有prototype屬性的構造函數/函數中?

但如果我刪除原型關鍵字在上面的代碼如下所示:

DoIHavePrototype.GetFnName = function() 
    { 
     return "DoIHavePrototype" 
    } 

我沒有得到錯誤的函數定義,而是我得到的錯誤,而調用方法 警報(CheckIt.GetFnName ())爲「CheckIt.GetFnName不是函數」

什麼是JS解釋器假定這是?

+3

如果將函數直接追加到類中,它將生成所謂的「靜態方法」,您只能像在'Array.from'中那樣調用您的類。所以在你的情況下,你應該像使用'DoIHavePrototype.GetFnName();'一樣使用你的類來調用它(不是它的實例)。 – Krusader

+0

工作就像一個charm.tnx讓我知道它創建靜態方法。 –

+0

我已經創建了一個真正的答案,所以如果它回答你的問題,請考慮它作爲答案。 – Krusader

回答

1

瞭解這個爲了能夠調用一些功能的對象的方法,有4種方法將其引入到對象中。

第一種方法是你已經在你的原代碼,這是對功能分配給對象的原型做了什麼:

Foo.prototype.myFunc = function() { .... } 

另一種方法是給它的構造函數中分配給this

function Foo() { 
    this.myFunc = function() { .... } 
} 

我們也可以直接將其指定爲實例:

var foo = new Foo(); 
var myFunc = function() { .... } 
foo.myFunc = myFunc 

最後,我們可以將功能綁定到實例:

var foo = new Foo(); 
var myFunc = function() { .... } 
var myFuncFoo = myFunc.bind(foo) 

最後一種情況是因爲有點特別我們有一個不是實例屬性的函數,但它的行爲像一個實例方法,因爲它的調用上下文被添加到實例中。

定義實例方法的最常見方法是分配給原型。構造函數上的prototype屬性是實例繼承的屬性,所以這就是我們放置東西的地方。請記住,實例繼承自prototype屬性,而不是構造函數,這一點很重要。將任何內容分配給構造函數屬性都不會使其成爲實例屬性。

如果我們想要一個綁定的方法,有時可以使用賦值爲this。例如:

function Foo() { 
    this.boundMeth = this.meth.bind(this) 
    this.val = "foo" 
} 

Foo.prototype.meth = function() { 
    console.log(this.val) 
} 

如果我們想通過instance.boundMeth()作爲值到另一個功能(例如,事件處理程序)這是非常有用的。在JavaScript中,與許多面向對象的語言,方法是綁定:

// Using Foo from the previous example 

function runner(fn) { 
    fn() 
} 
var obj = new Foo() 

runner(obj.meth) // Logs `undefined` 
runner(obj.boundMeth) // Logs `foo` 

當分配給構造函數的原型,您可以批量分配:

Foo.prototype = { 
    meth1: function() { .... }, 
    meth2: function() { .... }, 
} 

如果使用ES6,您還可以使用class關鍵字:

class Foo { 
    myFunc() { .... } 
} 

這與Foo.prototype.myFunc = function() { .... }相同。

+0

我不明白關於你使用綁定方法的未綁定/綁定方法的最後一個陳述,並提到關於將instance.boundMeth()作爲一個值傳遞給另一個函數。你可以帶我通過它嗎? –

+0

我會編輯答案來澄清。 – hayavuk

+1

有點偏離主題,但JavaScript中的「調用上下文」意味着'this'的值根據您調用函數*而改變,而不是它定義的位置。如果你用點符號'foo.bar()'調用任何函數,'this'就是點之前的東西。如果你沒有點地調用它,'this'是未定義的(在嚴格模式下)或全局對象(沒有嚴格模式)。無論您如何調用函數,bind()函數都可以讓我們更改/修改調用上下文*。 (更多在這裏:https://foxbunny.gitbooks.io/assimilate-js/content/this.html) – hayavuk

1

這也可以做,如果你仍然想要使用它作爲實例方法。

function DoIHavePrototype() 
{ 
    var a = 10; 

    this.GetFnName = function() { 
     return "DoIHavePrototype"; 
    } 
} 

CheckIt = new DoIHavePrototype(); 

alert(CheckIt.GetFnName()) 
1

如果您的附加功能直奔類就會產生所謂的static method,你可以從你的類在Array.from只能調用等。 所以你的情況,你應該把它用你的類(不是它的實例),像這樣DoIHavePrototype.GetFnName();

你可以MDN

相關問題