如何理解 JS 原型和原型链(隐式原型和显示原型)
1.原型
ES6中的 class
是一个语法糖,class实际上是一个函数。
// 父类(基类)
class People {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
console.log(this.name);
}
}
// 子类使用 extends 关键字 实现继承
class Programmer extends People {
constructor(name, type) {
// super() 调用父类的构造函数
super(name);
this.type = type;
}
code() {
console.log(`${this.name} is 正在写代码`);
}
job() {
console.log(`${this.name} is ${this.type}`);
}
}
const Gown = new Programmer('Gown', '前端工程师');
typeof People; // function
typeof Programmer; // function
显示原型和隐示原型
// 显示原型和隐示原型
console.log(Programmer.prototype); //People { sayName: [Function: sayName] }
console.log(Gown.__proto__); //People { sayName: [Function: sayName] }
console.log(Gown.__proto__ === Programmer.prototype); //true
基于原型的执行规则
1.获取属性John.name 或执行 sayName()方法
2.先获取属性自身的属性和方法
3.找不到自动通过隐示原型去查找
2.原型链
Gown.hasOwnProperty('name'); //true
Gown.hasOwnProperty('sayName()'); //false
Gown.hasOwnProperty('hasOwnProperty()'); //false
当我们「读取」John.hasOwnProperty 时,JS 引擎会做下面的事情:
- 看看
Gown
对象本身有没有 hasOwnProperty 属性。没有就走到下一步。 - 如果
Gown.__proto__
没有,那么浏览器会继续查看Gown.__proto__.__proto__
- 如果
Gown.__proto__.__proto__
也没有,那么浏览器会继续查看Gown.__proto__.__proto__.proto__
- 直到找到 hasOwnProperty 或者
__proto__
为 null。
上面的过程,就是「读」属性的「搜索过程」。
而这个「搜索过程」,是连着由 proto 组成的链子一直走的。
这个链子,就叫做「原型链」。
Object.prototype的隐式原型,_proto__永远指向null