JavaScript原型链

JavaScript原型链

要搞清楚原型链,我们首先了解什么是原型?每个函数都有prototype属性,我们称之为原型,又因为这个属性的值是一个对象,所以我们也称为原型对象

那么什么是对象呢?

这里我们要了解在JavaScript中对象是一种引用数据类型。我们可以通过很多种方式来创建一个对象。我们常用构造函数的方式来创建一个对象:

1
2
3
4
5
6
7
8
9
//构造函数
function People(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}

//生成实列
const p = new People('小明'16,'男')

那么,函数与对象的关系是怎么样的呢?

  • 函数是对象,对象都是通过函数创建的。
  • 函数与对象并不是简单的包含与被包含的关系。

在我们上面创建的对象中,通过定义常量实例化后,在原来构造函数中通过this赋值的方法或者属性,已经在实例化后成为了每个实例的实例属性实例方法,无法共享公共属性和方法。所以设计出了一个原型对象,来存储这个构造函数的公共属性及方法。

我们再下面一段代码了加深一下理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 构造函数
function Preson(name, age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 所有实例共享的公共方法
Preson.prototype.say = function (word) {
console.log(`${this.name}说:${word}`);
}

const p1 = new Preson('张三', 18,'男'); // 创建一个Person实例对象
p1.hasOwnProperty('say') // false 说明不是定义在其本身上的
p1.say('hello world'); // 调用公共方法 打印:张三说:hello world

可以看到我们实例对象实例p1调用到Person这个构造函数原型对象上的say()方法。但是为什么呢?明明只有在构造函数内部通过this来赋值的属性或者方法才会被实例所继承,为什么在构造函数原型对象上定义的say方法也能通过实例来调用到呢?这里就引出了原型链这个概念。

实际上原型对象中存在的构造函数指向了我们function创建的对象。并且每个对象都有一个__proto__属性,这个属性会指向实例对象构造函数原型对象,这样使得彼此之间存在一定的指向关系,能够使每个实列化对象能够使用构造函数原型对象的方法。

而这种指向关系,我们就称之为原型链。图解如下:

11

11

我们可以看到,它的__proto__属性指向了一个function Function原型对象,该原型对象为JS中所有函数的原型对象,而其__proto__属性也还是指向了function Object原型对象,所以验证了原型链的尽头为null,这一说法。

在开发的时候,要注意不要通过实例对象去改变其构造函数原型对象,这样会对其他通过该构造函数生成的实例对象造成影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//开发中需注意点

// 构造函数
function Preson(name, age) {
this.name = name;
this.age = age;
}
// 所有实例共享的公共方法
Preson.prototype.say = function (word) {
console.log(`${this.name}说:${word}`);
}

const p1 = new Preson('张三', 18); // 创建一个Person实例对象
const p2 = new Preson('李四', 20); // 新创建一个Proson实例对象
p1.say('hello world'); // 调用公共方法
p1.hasOwnProperty('say') // false 说明不是定义在其本身上的
p1.__proto__.do = function () {
console.log('往原型对象中添加方法');
}
p2.do(); // 打印出了-往原型对象中添加方法

原型链的尽头


我们可以看到,实例对象__proto__属性指向了一个构造函数原型对象,该构造函数的原型对象_proto_属性指向了Object原型对象,而其Object的原型对象_proto_属性指向了null,所以验证了原型链的尽头为null,这一说法。

11

欢迎关注我的其它发布渠道