Javascript原型链


构造函数

在 Javascript 中我们可以使用构造函数来声明一个类,然后利用new关键词实例化类。在构造函数中,this指向来该构造函数本身。

1
2
3
4
5
6
7
8
9
10
function Person(name) {
this.name = name;
}
Person.prototype.move = function() {

}

let person = new Person("Lily")
console.log(person.name) //Lily
person.move()

prototype

prototype 是一个对象,用于让所有的实例共享属性和方法。例如在上面的🌰中,我们在 Person 的prototype中添加了 move 方法,这样可以让所有的 Person 实例都继承这个方法。

__proto__

proto 是各个浏览器厂商实现的非标准 Javascript 属性。它指向构造函数的 prototype 对象.例如

1
2
3
4
5
6
7
8
9
10
``js
function Person(name) {
this.name = name;
}
Person.prototype.move = function() {

}

let person = new Person("Lily")
person.__proto__ === Person.prototype //true

constructor

每一个构造函数的原型上面都会有 constructor 对象,它指向构造函数本身,用代码来表示就是这样:

1
2
function Person{}
Person.prototype.constructor === Person

原型链

1
2
3
4
function Person{}
Person.prototype = {}
let person = new Person()
person.name

在 Javascript中,如果我们访问对象的某个属性,系统将先会在该对象上找,如果找不到,则会在该对象的proto 对象上继续找,如果没有会继续往上层找,即 Person.prototype.proto,直到最上层,系统会找到 Object.prototype,
Person.prototyoe.proto === Object.prototype,我们或许会问,Object.prototype.proto 又是什么呢?其实是 null 。这样就形成一条完整的原型链。

继承

Javascript中最常用的继承方法就是原型链继承了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Person() {}
function Student() {
Person.call(this)
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

//继承多个父类

function SuperClass() {}
function OtherSuperClass() {}
function ChildClass() {
SuperClass.call(this);
OtherClass.call(this);
}
ChildClass.prototype = Object.create(SuperClass.prototype)
Object.assign(SuperClass.prototype,OtherSuperClass.prototype)
ChildClass.prototype.constructor = ChildClass;

相信你看完上面关于原型的介绍很快就会明白上面继承的原理:子类继承并且重写父类的方法和属性,而又不会影响父类。这里我们利用 Object.create 方法。

new关键字

我们通常使用 new 关键字实例化Javascript对象,在new的过程中其实发生了如下过程:

1
2
3
4
5
6
function Person() {}
person = new Person();
/**等同于*/
person = new Object();
person.__proto__ = Person.protoype;
Person.call(person)

上面过程可以简单描述为,先创建一个 Object 实例,然后将该实例的 protot 属性指向Person.prototype ,最后再将 this 指针指向 Person,不是刚好符合我们上面所描述的那样吗?

总结

Javascript 基于原型链的设计让我们使用起来非常方便,但是同时原型链对于 Javascript 初学者来说相对比较难以理解,在平常的工作和学些过程中,我们一定要牢固掌握基础知识,多多积累知识和经验,这样才能从容面对工作中遇到的难题。