閱讀531 返回首頁    go 小米 go 小米6


secrets of the javascript Ninja (Function Prototypes)(javascript忍者的秘密)

       函數原型有很多用途,比如可以用來向一個函數實例上添加一些屬性,但是它的一個最主要用途是使JavaScript能夠以麵向對象的方式編程。

實例化和原型(Instantiation 和 prototypes)

所有函數默認的都會有一個含有空對象的prototype屬性,它的這個特性隻有在實例化後才會有用,為了能夠理解它的這種特性是多麼的重要,需要知道一個重要的原則:函數具有雙重功能,它可以作為一個平常的函數,也可以作為一個類。

我們可以通過下麵一個小例子來看看如何使用prototype屬性向一個函數上添加一個功能
  1. function Ninja(){} Ninja.prototype.swingSword=function(){ return true; } var ninja=Ninja(); alert(ninja);//undefined,說明不是Ninja的一個實例 var ninja2=new Ninja(); alert(ninja2.swingSword);//true 
  1. 從上麵的這個例子,我們可以發現以下兩個問題:

         1.為了產生一個函數的實例對象必須使用new操作符調用該函數。

         2.swingSword變成了Ninja的實例ninja2的一個屬性。

 

 

對於函數Ninja來說,由於使用new操作符調用它,我們也可以認為他是一個構造函數。這就意味著,它使用new操作符調用函數的時候,該函數中this所指向的上下文就是對象自身的實例(即和prototype相同),這段話不是太好理解,來讓我們看一個例子:

function Ninja(){ this.swung = false; // Should return true this.swingSword = function(){ return !this.swung; }; } // Should return false, but will be overridden Ninja.prototype.swingSword = function(){ return this.swung; }; var ninja = new Ninja(); alert(ninja.swingSword()); 

從上麵的例子我們可以發現實例對象調用它的同名方法的順序

 

1.綁定在prototype上的屬性。

2.綁定在構造函數內的屬性。

 

 

 

 

另外一個需要了解的是綁定在prototype上的屬性,他可以被更新和改變,即使一個對象被實例化後:如下

 

function Ninja(){ this.swung = true; } var ninja = new Ninja(); Ninja.prototype.swingSword = function(){ return this.swung; }; alert(ninja.swingSword()); 

 

 

 

 

 

對象類型

還是以例子說話:

function Ninja(){} var ninja = new Ninja(); alert(typeof ninja); alert(ninja instanceof Ninja); alert(ninja.constructor == Ninja); 

從上麵的例子中,我們可以看到:

 

1.所有的示例對象如果使用typeof檢測都是object類型

2.instanceof 實例對象是由那個函數生成的。

3.任何實例都有個constructor屬性,用來引用生成該實例對象的構造函數

 

 

 

 

為了證明第三個觀點,下麵來看一個簡單的例子:

 

 

var ninja = new Ninja(); var ninja2 = new ninja.constructor(); alert(ninja2 instanceof Ninja);//true 

 

 

 

 

 

 

繼承與prototype鏈

在這裏我們還可以看到instanceof的一個重要特性:

 

function Person(){} Person.prototype.dance = function(){}; function Ninja(){} // Achieve similar, but non-inheritable, results Ninja.prototype = Person.prototype; Ninja.prototype = { dance: Person.prototype.dance }; // Only this maintains the prototype chain Ninja.prototype = new Person(); var ninja = new Ninja(); alert(ninja instanceof Ninja);//true alert(ninja instanceof Person);//true alert(ninja instanceof Object);//true 

 

有很多方法從函數的prototype屬性上複製功能(方法和函數),但是隻有一種情況能夠形成prototype鏈。即:SubFunction.prototype = new SuperFunction();.

 

 

 

 

 

 

HTML prototypes

在Internet Explorer 8, Firefox, Safari, 和 Opera這些瀏覽器中這些可以使用prototype擴展dom元素: 來看看一個簡短的例子:

<div >I'm going to be removed.</div> <div >Me too!</div> HTMLElement.prototype.remove = function(){ if ( this.parentNode ) this.parentNode.removeChild( this ); }; // Old way var a = document.getElementById("a"); a.parentNode.removeChild( a ); // New way document.getElementById("b").remove(); 

最後更新:2017-04-02 00:06:44

  上一篇:go ASP.NET3.5中AJAX控件
  下一篇:go opengl的一些小問題