前言
对象实例化和继承这两个过程和原型对象(Func.prototype)密切相关,总觉得他们的实现原理很相似,想要一探究竟,结果迷失在源码里长达数小时……直到伟大的MDN点醒了我
new 的实现原理
new 的过程很好理解,先想象原型链长啥样
要实现这样的效果,我们需要这几步操作:
- 创建一个新对象
{} - 将该对象内置的原型对象([[prototype]])设置为构造函数prototype引用的原型对象,从而继承原型上的方法
- 将
this指向该空对象,用this执行构造函数中的代码,例如Function.call(),获取属性 - 如果构造函数返回了一个对象res,就将该返回值res返回,如果返回值不是对象,就将创建的对象返回
继承如何实现
首先明确一个类的基本组成:
class People {
constructor(age, gender, interests, subject) {
this.age = age; // 实例属性
this.gender = gender;
}
type = 'normal'; // prototype属性
// prototype方法
work() {
//... working
}
static id = '000'; // 静态属性,无法被继承、实例获取
}
除了constructor里面定义的实例属性,静态属性,其他都在prototype上。
现在来逐步继承父类中的属性:
- 继承父类constructor中的实例属性,并添加自有属性
function Teacher(age, gender, interests, subject) {
// 将Teacher的实例作为上下文调用Person的构造器
Person.call(this, age, gender, interests);
this.subject = subject; // Teacher的自有属性
}
- 继承父类的prototype中的属性和方法
// 复制一个父类prototype对象(注意是一个新对象)
Teacher.prototype = Object.create(Person.prototype);
// ps: 这个时候Teacher.prototype.constructor = Person;
- 调整原型链
Teacher.prototype.constructor = Teacher;
- 添加子类方法
Teacher.prototype.greeting = function() {...}
以上内容如有错误还请各位大佬指点!
Reference:
segmentfault.com/a/119000002…
developer.mozilla.org/zh-CN/docs/…