(这篇会延续Constructor Function的内容,来解释 Prototype 和 Prototypal inheritance。)
(想看结论可以看粗体跟移到最下面。)
在 4. 关於 Constructor Function 解释建构子函式的文章时,有提到把属性(properties)和方法(methods)都丢进建构子,这种建立物件的方式会占用到大量的记忆体。
我们可以先看看这个例子:
function Person(name, age, country){
this.name = name,
this.age = age,
this.country = country,
this.sayHi = function(){
console.log(this.name + " says Hi.");
}
}
let Tina = new Person("Tina", 22, "Taiwanese");
let Winnie = new Person("Winnie", 108, "Japanese");
console.log(Tina.sayHi === Winnie.sayHi); // output: false
Tina.sayHi
和Winnie.sayHi
的比较结果是不相等,要怎麽解释这个结果呢?
也就是说,即使他们定义的method一模一样,也会被当成不同的物件 → 指向不同的记忆体位置
那麽, 假设今天要制造一百个物件,就会制造一百个sayHi()
→ 占用一百个记忆体位置
这时侯我们可以利用prototype:
function Person(name, age, height){
this.name = name,
this.age = age,
this.country = country
}
Person.prototype.sayHi = function() { // 在Person的prototype属性定义sayHi()
console.log(this.name + " says Hi");
}
let Tina = new Person("Tina", 22, "Taiwanese");
let Winnie = new Person("Winnie", 108, "Japanese");
console.log(Tina.sayHi === Winnie.sayHi); // output: true
从这里可以知道,Tina.sayHi
和Winnie.sayHi
两个函式严格相等(指向同样的记忆体位置),这样就可以解决占用记忆体的灾难。
那接下来要来了解,为什麽加入prototype可以解决这个问题?
所以我们要来认识JS的继承(inheritance)和原型链(Prototype chain):
Prototype
(原型),而prototype本身也是一个object(物件)。null
,或参考至其他物件。In JavaScript, objects have a special hidden property [[Prototype]] (as named in the specification), that is either null or references another object. That object is called “a prototype”:
在程序语言中,这个行为被称作 「原型继承」。 (← 全文重点
When we read a property from object, and it’s missing, JavaScript automatically takes it from the prototype. In programming, this is called “prototypal inheritance”.
从我们刚刚执行的例子,我们可以执行console.log(Tina);
来了解他们的阶层关系:
Tina
本身是建构子Person
创造出来的实例(instance)。Person()
。Object()
。由此可知,他们的继承(查找)机制是这样子:
Tina ---> Person.prototype(红色框) ---> Object.prototype(绿色框) ---> Null
(JS 使用 constructor function 来定义物件的属性与方法,而产生出的新物件被称为实例(Instance)。)
最後补充一下MDN的定义:
讲到继承,JavaScript 就只有一个建构子:物件。
每个物件都有一个连着其他原型(prototype)的私有属性(private property)物件。 原型物件也有着自己的原型,於是原型物件就这样链结,直到撞见 null 为止:null 在定义里没有原型、也是原型链(prototype chain)的最後一个链结。
引用自 继承与原型链 - JavaScript | MDN
做个结论:
→ 每个JS里的物件(object),都继承(inheritance)自该物件的原型(Prototype),并保留其属性和方法。
→ 使用建构子函式产生实例以後,这些被产生的物件之间的连结被称为原型链(Prototype chain)。
→ 当我们需要读取一个物件的属性,却找不到时,JS会自动从从该物件的prototype查找,也就是原型继承(prototypal inheritance)。
参考资料:
【如内文有误还请不吝指教>< 谢谢阅览至此的各位:D】
-----正文结束-----
本节是以 Golang 上游 1a708bcf1d17171056a42ec1597ca8848c...
开发过程中常常会需要使用console.log()来检视输出是否正确,所以能够妥善运用各种conso...
Youtube连结:https://bit.ly/2Uv2sBf 在我们还没学资料结构前,通常都用...
你最万能的游戏机 Windows PC windows 为市占率最高的电脑作业,他满足了人们音乐, ...
如果想快速使用 Hook ,其实就参考 Hook 概观分的五个面向,包含一定会用也最常用的 Stat...