JavaScript 每一個物件(包含函數)都有原型這個屬性用來繼承屬性與方法。
原型會去參考另一個物件,而那個物件的原型又可以去參考另一個物件。
如下圖:
先看紅色的部分,obj.prop1 本身就是 obj 的屬性,不用去往外找;
如果是 obj.prop2,在 obj 屬性裡面找不到,所以去找它的原型的物件裡找,結果找到了;而 obj.prop3 在obj中找不到,往外 在 proto 中也找不到,又再往 proto 的原型找才找到並返回 prop3。
雖然看起來好像是obj自已的屬性,其實那是原型,或是原型的原型的屬性,
這種方式就叫做「原型鍊」。
這跟之前說過的範圍鍊(Scope Chain)不一樣,範圍鍊是指變數的取用;
而原型鍊(Prototype Chain)是指屬性與方法的取用。
此外,看剛剛那張圖灰色的部分,obj2 是另一個物件,它也可以與 obj 共有相同的原型物件,也就是 obj.prop2 與 obj2.prop2 會回傳一樣的屬性,因為它們指向的記憶體位址一樣。
原型鍊的好處就是,你不需要再 obj.proto.proto.prop3 ,直接 obj.prop3 就可以了。
一個已存在構造函數的對象中不能添加新屬性、函數
function Person(name,age){
this.name=name;
this.age=age;
}
//一個已存在構造函數的對象中不能添加新屬性、函數
Person.sayHi=function(){
console.log('Hi! my name is '+this.name);
}
var student = new Person('Ivy',20);
student.sayHi();//Uncaught TypeError: student.sayHi is not a function
如果使用原型就可以給建構函數增加屬性與方法
function Person(name,age){
this.name=name;
this.age=age;
}
//如果使用原型就可以增加屬性與方法
Person.prototype.sayHi=function(){
console.log('Hi! my name is '+this.name);
}
var student = new Person('Ivy',20);
student.sayHi();//Hi! my name is Ivy