JS 原型鍊(Prototype Chain)
物件擁有自己的屬性,他可以繼承原型,而原型也可以繼承其他原型,原先的物件可以使用.
取用屬性,而如果在原本物件找不到此屬性,他就會向上查找直到找到屬性或是null
(找到 null 就會報錯),而如果有從一個原型新增出兩個實體,他們會共用同一個原型的方法
特性
- 一樣具有物件特性
- 向上查找
- 原型可共用發方法及屬性
原型在哪裡
以下寫法為非正規寫法
以下範例可以看到陣列的原型,也可以為他的原型加上屬性,因為屬性是共用的,假如你新增其他陣列也可以使用getLast()
方法。
建構式自定義原型
利用函式建構物件,使用Prototype
製作原型功能,在過去無規範如何製作原型功能,所以大多採用__proto__
製作,後來ECMAScript
規範要使用[[Prototype]]
製作原型功能,
但之前開發者大多使用__proto__
原型所以瀏覽器還保留此方法,所以如果現在看到[[Prototype]]
就是瀏覽器還沒更新前的__proto__
是往上追朔的原型。
proto
不屬於正規 JS
,他是瀏覽器的方法,會導致同層所有資料被賦予新方法
prototype
是正規的JS
方法,在為建構函式新增方法時、原型作多層串接時都會使用
以下範例使用函式建構物件
function human(name, city) { this.name = name; this.city = city; }
var Joe = new human("joe", "Tiawan");
human.prototype.work = function () { console.log(`${this.name}工作`); };
console.log(Joe.work());
console.log(human.prototype === Joe.__proto__);
|
Object.create 建立多層繼承
使用Object.create
繼承方法,
當繼承函式執行時,this
值指向繼承的物件,而不是在函式內擁有屬性的原型物件。
為啥總要修正 constructor。補充
function Animal(family) { this.kingdom = "動物界"; this.family = family; }
Animal.prototype.move = function () { console.log(`${this.name}走路`); };
function Cat(name, color, size) { Animal.call(this, "貓科"); this.name = name; this.color = color; this.size = size; }
Cat.prototype = Object.create(Animal.prototype); Cat.prototype.constructor = Cat; Cat.prototype.detail = function () { console.log(`名子:${this.name}, 顏色:${this.color}, 大小: ${this.size}`); };
var Amy = new Cat("艾米", "棕色", "小型"); var Kumo = new Cat("哭某", "白色", "大型"); Amy.detail(); Amy.move();
Kumo.detail(); Kumo.move();
|
使用 ES6 新語法 class 建立物件
將上述的繼承與建立物件改成使用 class 語法,類別的主體指的是被大括號({})包含的部分,你可以在這裡面定義類別成員(members),例如方法(methods)或建構子(constructors)。
若在子類別中有建構子(constructor),要使用 this 前則必須先呼叫 super()函式。
class MDN
class Animal { constructor(family) { this.kingdom = "動物界"; this.family = family; }
echoFamily() { console.log(`${this.name}走路`); } }
class Cat extends Animal { constructor(name, color, size) { super("貓科"); this.name = name; this.color = color; this.size = size; }
detail() { console.log(`名子:${this.name}, 顏色:${this.color}, 大小: ${this.size}`); } }
var Amy = new Cat("艾米", "棕色", "小型");
Amy.echoFamily(); Amy.detail();
|