1. 程式人生 > 實用技巧 >js 的原型和原型鏈

js 的原型和原型鏈

js 的原型和原型鏈

目錄

建構函式建立物件:

function Person() {

}
var person = new Person();
person.name = 'Kevin';
console.log(person.name) // Kevin

Person 就是一個建構函式,我們使用 new 建立了一個例項物件 person

prototype

每個函式都有一個 prototype 屬性
每一個JavaScript物件(null除外)在建立的時候就會與之關聯另一個物件,這個物件就是我們所說的原型,每一個物件都會從原型"繼承"屬性

function Person() {

}
// 雖然寫在註釋裡,但是你要注意:
// prototype是函式才會有的屬性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin

proto

每一個JavaScript物件(除了 null )都具有的一個屬性,叫proto,這個屬性會指向該物件的原型

function Person() {

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

constructor

每個原型都有一個 constructor 屬性指向關聯的建構函式 例項原型指向建構函式

function Person() {

}
console.log(Person === Person.prototype.constructor); // true

function Person() {

}

var person = new Person();

console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
// 順便學習一個ES5的方法,可以獲得物件的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

例項與原型

function Person() {

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) // Daisy

delete person.name;
console.log(person.name) // Kevin

在這個例子中,我們給例項物件 person 添加了 name 屬性,當我們列印 person.name 的時候,結果自然為 Daisy。

但是當我們刪除了 person 的 name 屬性時,讀取 person.name,從 person 物件中找不到 name 屬性就會從 person 的原型也就是 person.proto ,也就是 Person.prototype中查詢,幸運的是我們找到了 name 屬性,結果為 Kevin。

原型與原型

var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin

原型鏈

什麼是原型鏈

原型鏈的核心就是依賴物件的_proto_的指向,當自身不存在的屬性時,就一層層的扒出建立物件的建構函式,直至到Object時,就沒有_proto_指向了。

如何分析原型鏈?

因為_proto_實質找的是prototype,所以我們只要找這個鏈條上的建構函式的prototype。其中Object.prototype是沒有_proto_屬性的,它==null。

console.log(Object.prototype.__proto__ === null) // true

JavaScript 預設並不會複製物件的屬性,相反,JavaScript 只是在兩個物件之間建立一個關聯,這樣,一個物件就可以通過委託訪問另一個物件的屬性和函式,所以與其叫繼承,委託的說法反而更準確些