0%

JavaScript 原型链深入

原型和原型链

JavaScript 通过原型链实现继承。

构造函数

1
2
3
4
5
function Person(name) {
this.name = name
}

const person = new Person('Alice')

原型对象

1
2
3
4
5
Person.prototype.sayHello = function() {
console.log(`Hello, ${this.name}`)
}

person.sayHello() // Hello, Alice

proto

实例的 __proto__ 指向构造函数的 prototype。

1
person.__proto__ === Person.prototype // true

原型链

1
2
3
person.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null

继承

原型继承

1
2
3
4
5
6
7
function Student(name, grade) {
Person.call(this, name)
this.grade = grade
}

Student.prototype = Object.create(Person.prototype)
Student.prototype.constructor = Student

ES6 class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
constructor(name) {
this.name = name
}

sayHello() {
console.log(`Hello, ${this.name}`)
}
}

class Student extends Person {
constructor(name, grade) {
super(name)
this.grade = grade
}
}

总结

理解原型链对掌握 JavaScript 很重要。ES6 class 简化了继承,但底层仍是原型。

示例:手动实现继承函数

1
2
3
4
function extend(sub, sup) {
sub.prototype = Object.create(sup.prototype);
sub.prototype.constructor = sub;
}

原型链深度与性能

浏览器查找属性沿着原型链向上,如果链条过长会增加查找时间。尽量避免在关键路径上频繁访问深层属性。

ES6 class 实际编译

Babel 将 class 转换为如下形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

var Person = function Person(name) {
_classCallCheck(this, Person);
this.name = name;
};

Person.prototype.sayHello = function sayHello() {
console.log("Hello, " + this.name);
};

这些代码仍然使用原型机制。

原型链的用途

  • 模拟继承
  • 实现多态
  • 提供共享方法

面试题

如何判断一个对象是某个构�> 如何判断一个对象是某个构�> 如何判断一个对象�链:

1
2
3
4
5
function isInstanceOfunction nstrufunction isInstanceOfunctectfunction isInstanceOfunction nstrufunction isI (function isInstanceOfunction ns) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}

注意事项

  • 修改原型会影响所有实例
  • 不要在运行时频繁修改 prototype,�- 不要在运行时频�## - 不要在运行时频繁修改 proto��底层设计,- 不要在运行时频繁修改 prototype`,�也有助于理解框架如 Vue、React 的对象模型。

附加内容补充1
附加内容补充2
附加内容补充3
附加内容补充4
附加内容补充5
附加内容补充6