Function.prototype是什么?https://segmentfault.com/q/1010000007159851
JavaScript中Function原型及其prototype屬性的簡單應用:https://www.cnblogs.com/amazingbook/p/7210310.html
大家都知道在JavaScript中是沒有類的概念的,但是卻是有對象的概念的。有的人可能理解對象和類有些迷糊,這里簡單的概括一下他們之間的區別:
類:抽象的概念,例如人,動物,汽車等都可以抽象成一個類
對象:是指這種概念中的實體,例如“一個帶着紅帽子的小男孩”、“一輛紅色的奔馳汽車”,“一只白色的小貓”都是實體也就是對象
實例化:就是指以類為基礎構建一個實體。類所擁有的特征,其實例化對象,也一定擁有這些特征,而且實例化后可能擁有更多特征。
用Java代碼表示:
1 /* 2 人 3 屬性: 身高 height 4 行為: 說話 speak 5 */ 6 class Person 7 { 8 private int age; 9 public void setAge(int a) 10 { 11 age = a; 12 } 13 Person() //構造函數,而且是空參數 14 { 15 this.name = name; 16 this.age = age; 17 System.out.println("name="+name+" age="+age); 18 } 19 public int getAge() 20 { 21 return age; 22 } 23 void speak() 24 { 25 System.out.println("age="+age); 26 } 27 } 28 class PersonDemo 29 { 30 public static void main(String[] args) 31 { 32 Person p = new Person("張三",25); 33 } 34 } 35 //運行結果 ==> name=張三 age=25
我們在JavaScript中用到對象時是沒有類的概念的,但是程序的世界里千變萬化,博大精深,這里提供一種方法,可以用function構造出一種假象類,從而實現類的構造
1 /* 2 * 這里同樣使用人來構造一個類 3 */ 4 function Person(name,age) 5 { 6 this.name = name; 7 this.age = age; 8 } 9 var people = new Person("張三",25);
下面就來介紹一下Function:
Function是由function關鍵字定義的函數對象的原型
在javascript中,多出了一個原型的概念。所謂原型,其實就是一個對象的本質,但復雜就復雜在,原型本身也是對象,因此,任何一個對象又可以作為其他對象的原型。Function就相當於一個系統原型,可以把它理解為一種“基本對象類型”,是“對象”這個概念范疇類的基本數據類型。除了Function之外,其實還有很多類似的首字母大寫的對象原型,例如Object, Array, Image等等。有一種說法是:javascript中所有的一切都是對象(除了基本數據類型,其他的一切全是對象),所有的對象都是Object衍生出來的。(按照這種說法,我們應該返回去再思考,上面說的類的假設是否成立。)
極其重要的prototype概念
prototype的概念在javascript中極其重要,它是javascript中完成上面說的“一切皆對象”的關鍵。有了prototype,才有了原型,有了原型,才有了javascript五彩繽紛的世界(當然,也有人說是雜亂的)。我們可以這樣去理解prototype:世界上本沒有javascript,上帝說要有Object,於是有了Object,可是要有Function怎么辦?只需要對Object進行擴展,可是如何擴展?只需要用prototype……當然,這是亂扯的,不過在javascript中,只要是function,就一定會有一個prototype屬性。實際上確實是這樣
1 Function.prototype.show = function() {...}
在原型的基礎上通過prototype新增屬性或方法,則以該對象為原型的實例化對象中,必然存在新增的屬性或方法,而且它的內容是靜態不可重載的。原型之所以被稱為原型,可能正是因為這種不可重載的特質。
比如上面的這段代碼,會導致每一個實例化的function,都會具備一個show方法。
注意上面橙色加粗的文字,每一個實例化的function,都會具備一個show方法那我們該如何使用這個方法呢?
1 Function.prototype.show = function() 2 { 3 return "我是一個函數的新方法"; //函數需要有返回值! 4 } 5 Function.show(); //輸出=>我是一個函數的新方法 6 Function; //Function的原型為 =>function Function() { [native code] } 7 var f = new Function(); 8 f.show(); //輸出=>我是一個函數的新方法
而如果我們自己創建了一個類,則可以通過prototype將之轉化為原型:
1 function Cat() {...} 2 Cat.prototype.run = function() {}; 3 var cat1 = new Cat();
這時,對於cat1而言,Cat就是原型,而該原型擁有一個run的原始方法,所以無論實例化多少個Cat,每一個實例化對象都有run方法,而且該方法是不能被重載的,通過cat1.run = function(){}是無效的。
為了和其他語言的類的定義方法統一,我們可以將這種原型屬性在定義類的時候,寫在類的構造里面:
1 function Cat() { 2 .... 3 Cat.prototype.run = function() {}; 4 }
new Function()是函數原型的一個實例化
在理解了Function原型的概念之后,再來看new Function()就顯得很容易了。
1 var message = new Function('msg','alert(msg)'); 2 // 等價於: 3 function message(msg) { 4 alert(msg); 5 }
new Function(參數1,參數2,…,參數n,函數體),它的本意其實是通過實例化一個Function原型,得到一個數據類型為function的對象,也就是一個函數,而該變量就是函數名。
小結:
本文參考了 http://www.techug.com/post/utm_javascript.html 這篇文章,在筆者看到原文中說在原型的基礎上通過prototype新增屬性或方法,則以該對象為原型的實例化對象中,必然存在新增的屬性或方法,而且它的內容是靜態不可重載的這句話但是一時卻不知道如何去調用新添加的方法,后來發現prototype新增方法方法里必須要有返回值,並且需要通過Function來進行調用,而且在添加show()方法后輸入Function輸出的結果為
1 function Function() { [native code] }