學到原型的時候感覺頭都大了/(ㄒoㄒ)/~~ 尤其是ptototype和__proto__ 傻傻分不清 通過多番查找資料,根據自己的理解,總結如下: 一、構造函數: 構造函數:通過new關鍵字可以用來創建特定類型的對象的函數。比如像Object和Array,兩者屬於內置的原生的構造函數,在運行時會自 ...
學到原型的時候感覺頭都大了/(ㄒoㄒ)/~~ 尤其是ptototype和__proto__ 傻傻分不清 通過多番查找資料,根據自己的理解,總結如下:
一、構造函數:
構造函數:通過new關鍵字可以用來創建特定類型的對象的函數。比如像Object和Array,兩者屬於內置的原生的構造函數,在運行時會自動的出現在執行環境中,可以直接使用。如下:
var arr = new Array();//使用Array構造函數創建了一個array實例arr arr[0]="a"; arr[1]="b"; alert(arr);//a,b var obj=new Object();//使用Object構造函數創建了一個Object實例obj obj.name="c"; obj.age=12; alert(obj.name);//c
我們可以自定義的創建構造函數,併為其自定義屬性和方法,如:
//創建構造函數Person function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert(this.name)// }; } //使用new關鍵字,來生成Person實例 var person1=new Person("Tom",22); var person2=new Person("Jerry",21); person1.sayName();//Tom person2.sayName();//Jerry
註意以下幾點:
- 構造函數的名字始終要以大寫字母開頭(主要是為了區別於非構造函數,也即是區別於普通函數)
- 構造函數也就是函數,定義構造函數和定義普通函數的語法一樣。構造函數和普通函數的區別在於:使用他們的方式不同。任何函數只要使用new操作符來調用,那他就可以作為構造函數;不使用new操作符來調用就是普通函數
function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert(this.name)// }; } //當做構造函數使用 var person=new Person("Tom",22); person.sayName();//Tom //當做普通函數使用 Person("Jerry",30);//添加到window sayName();//Jerry 等同於window.sayName();
二、原型對象:
每個函數都有一個prototype屬性,它是一個指向原型對象的指針,原型對象在定義函數時同時被創建,原型對象的用途是包含所有實例共用的屬性和方法
function Person(){ } //自定義原型對象的屬性和方法 Person.prototype.name="Tom"; Person.prototype.age=25; Person.prototype.sayName=function(){ alert(this.name); }; //原型對象中的所有屬性和方法 都會自動被所有實例所共用 var person1=new Person(); var person2=new Person(); person1.sayName();//Tom person2.sayName();//Tom
只要創建了一個新函數,每個函數在創建之後都會獲得一個prototype的屬性,這個屬性指向函數的原型對象(原型對象在定義函數時同時被創建),此原型對象又有一個名為“constructor”的屬性,反過來指向函數本身,達到一種迴圈指向,
如在上邊的例子中:alert(Person.prototype.constructor===Person);//會返回true
function Person(){} alert(Person.prototype.constructor===Person);//true
三、__proto__(註意這裡proto左右兩邊都有兩個"_")
當調用構造函數創建一個新實例後,該實例的內部將包含一個指針[[Prototype]],該指針指向創建它的構造函數的原型,在腳本上沒有標準的方法來訪問[[Prototype]],但大多數瀏覽器都支持通過__proto__來訪問。
function Person(){ } //自定義原型對象的屬性和方法 Person.prototype.name="Tom"; Person.prototype.age=25; Person.prototype.sayName=function(){ alert(this.name); }; //原型對象中的所有屬性和方法 都會自動被所有實例所共用 var person1=new Person(); var person2=new Person(); person1.sayName();//Tom person2.sayName();//Tom alert(person1.__proto__===Person.prototype);//true
以上述的示例代碼為例,各個對象之間的關係如下圖所示:
總結:
①只要創建了一個函數,該函數的原型對象也隨之同時被創建出來,原型對象中的屬性和方法被經由其相對應的構造函數所創建的實例所共用
②每個函數在創建之後都會獲得一個prototype的屬性,這個屬性指向該函數的原型對象
③每個對象的__proto__屬性都指向其構造函數的原型