原型:函數都有prototype屬性,稱之為原型,也稱為原型對象
原型可以放一些屬性和方法,共享給實例對象使用
原型可以做繼承
原型鏈:對象都有__proto__屬性,這個屬性指向它的原型對象,原型對象也是對象,也有__proto__屬性,指向原型對象的原型對象,這樣一層一層形成的鏈式結構稱為原型鏈,最頂層找不到則返回 null
1.javascript原型鏈(經典函數構造器 + prototype)
function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}`);
};const alice = new Person('Alice');
alice.sayHello(); // Hello, my name is Aliceconsole.log(alice.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
解釋:
-
每個對象都有一個內部屬性
[[Prototype]]
(常用__proto__
訪問),指向它的原型對象。 -
當訪問對象的屬性或方法時,如果自身沒有,會沿著
[[Prototype]]
一層層往上找,這個查找鏈就是原型鏈。 -
上面例子中,
alice
訪問sayHello
方法時沒在自身屬性里找到,就去它的原型對象Person.prototype
查找。 -
Person.prototype
的原型是Object.prototype
,這構成了原型鏈的多層關系。 -
Object.prototype
的原型是null
,鏈條終點。
2.TypeScript 版本(class 語法)
class Person {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}`);}
}const alice = new Person('Alice');
alice.sayHello(); // Hello, my name is Aliceconsole.log(Object.getPrototypeOf(alice) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null
解釋:
-
TypeScript 使用
class
關鍵字聲明類,語法更現代,代碼更清晰。 -
sayHello
是類的方法,實際掛載在Person.prototype
上,實例通過原型鏈訪問。 -
Object.getPrototypeOf()
用來獲取對象的原型,效果和__proto__
類似,但更標準安全。 -
原型鏈關系和JavaScript版本完全一樣:實例原型 → 類的
prototype
→Object.prototype
→null
。
3.總結
-
JavaScript版本用構造函數和顯式原型,適合傳統理解原型鏈機制。
-
TypeScript版本用類語法,更符合現代代碼風格,本質上還是基于JavaScript原型鏈實現。