原型與原型鏈 一. 普通對象與函數對象 JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。下麵舉例說明 在上面的例子中 o1 o2 o3 為普通對象,f1 f2 f3 為函數對象。怎麼區分,其實很簡單,凡是通 ...
原型與原型鏈
一. 普通對象與函數對象
- JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。下麵舉例說明
var o1 = {};
var o2 = new Object();
var o3 = new f1();
function f1(){};
var f2 = function(){};
var f3 = new Function('str');
typeof Object;//function
typeof Function;//function
typeof f1;//function
typeof f2;//function
typeof f3;//function
typeof o1;//object
typeof o2;//object
typeof o3;//object
在上面的例子中 o1 o2 o3 為普通對象,f1 f2 f3 為函數對象。怎麼區分,其實很簡單,凡是通過 new Function() 創建的對象都是函數對象,其他的都是普通對象。f1,f2,歸根結底都是通過 new Function()的方式進行創建的。Function Object 也都是通過 New Function()創建的。
二.構造函數
function Person(name, age, job){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person('mike',15);
var person2 = new Person('nike',18);
上例中person1和person2為Person的實例,兩個實例中都有隱含的
==constructor==屬性(通過原型對象繼承得到),該屬性指向構造函數Person
三.原型對象
- 我們創建的每個函數都有一個prototype(原型)屬性,指向函數的原型對象。換句話說,prototype就是通過調用構造函數而創建的那個對象實例的原型對象,使用原型對象即可以讓所有對象實例共用它所包含的屬性和方法,可類比於父子類(繼承)。
- 創建新函數時,其prototype屬性指向的原型對象會自動獲得一個constructor(構造函數)屬性,該屬性指向包含prototype的函數,也就是構造函數
function Person(name, age, job){
Person.prototpe.name = father;
Person.prototpe. = 28;
Person.prototpe.sayName = function(){
alert(this.name);
}
}
var person1 = new Person();
person1.sayName();//'mike'
var person2 = new Person();
person2.sayName();//'nike'
person1.sayName == person2.sayName;//true
person1.name = 'joy';
person1.sayName();//'joy'
通過為構造函數Person的原型對象創建屬性,person1,person2將繼承Person.prototype的屬性,如果實例定義了與原型對象同名屬性,原型對象屬性則會被覆蓋。
補充:更簡單的原型語法
function Person(){}
Person.prototype = {
name:'',
age:'',
sayName:function(){
}
}
==註意==:該方法的原型對象的constructor屬性不再指向Person,此時例中指向Object(新new的一個對象),如若需要可在Person.pertotype的字面量中添加:==constructor:Person,==
四.__proto__
JS 在創建對象(不論是普通對象還是函數對象)的時候,都有一個叫做__proto__ 的內置屬性,用於指向創建它的構造函數的原型對象。
- 普通對象的__proto__指向這個對象(this)的構造函數的prototype;
函數對象的__proto__全部都是指向Function的prototype。
對象 person1 有一個 __proto__屬性,創建它的構造函數是 Person,構造函數的原型對象是 Person.prototype ,所以:
==person1.__proto__ == Person.prototype==
不過,要明確的真正重要的一點就是,這個連接存在於實例==person1==與構造函數==Person==的原型對象==Person.prototype==之間,而不是存在於實例person1與構造函數Person之間。
js高級程式設計圖
五.Prototype
當我們創建一個函數時:
var Person = new Object()
Person 是 Object 的實例,所以 Person 繼承了Object 的原型對象Object.prototype上所有的方法:
六.Object.getPrototypeOf(obj)
獲取對象的原型
總結
- 原型和原型鏈是JS實現繼承的一種模型。
- 原型鏈的形成是真正是靠__proto__ 而非prototype
- 對象通過__proto__屬性訪問原型,構造函數通過prototype屬性訪問原型