javascript高级篇之原型和原型链

1,083 阅读3分钟

本人已参与「新人创作礼」活动,一起开启掘金创作之路。

什么是原型对象?

js分为函数对象和普通对象 ,每个对象都有__proto__属性,但是只有函数对象才有prototype属性。prototype指向一个对象,"function".prototype的名字就是原型对象。

举个例子

//这是一个构造函数  (构造函数也是函数)
const Persion(name,money){
    this.name = name;
    this.money = money
}

那么Persion身上就有一个prototype 例如↓

Persion.prototype

原型对象的作用

保存公共状态

举个例子

有那么一个需求,name和sex自定义。money字段共用且固定

//第一个构造函数
const Person(name,sex){
    this.name = name;
    this.sex = sex;
}
Person.prototype.money = 0;

const per1 = new Person('阿巴',"男");
const per2 = new Person('呱啦',"女");

per1.money  ===  0  //true
per2.money  ===  0  //true

per1和per2在本身找不到money这个属性的时候就会去其构造函数的原型对象上面寻找这个属性。而money这个属性被挂载的Person的原型对象上(也就是per1和per2构造函数都原型上) ,per1和per2又是Person的实例。所以per1和per2可以在本身没有money的情况下访问到money这个变量。

per1和per2都通过Person来构建实例。但只有他们的name和sex属性是不一样的。money属性就实现了共用。

在原型对象这个对象上,有一个属性 .constructor 指向其原型对象所在的函数。

拿上面的案例举个例子

Person.prototype.constructor === Person //true

这一整个概念,我们称之为原型。

e5bdab96716f42d9990a54f4e398dbe2.png

原型链

我们上面介绍的prototype被称为显式原型。

还有一个隐式原型 __ proto__

__ proto__只存在于对象上。对象的__proto__(隐式原型)指向的就是其构造函数的显式原型。

例如↓


const Person(name,sex){
    this.name = name;
    this.sex = sex;
}

const per = new Person("阿巴","男");

per.__ proto __  ==== Person.prototype  //true
per.__ proto__(隐式原型)指向Person.prototype(显示原型),

但Person.prototype这个原型对象也是一个对象,他也有一个自己的__proto__属性。

那Persion.prototype.proto(原型对象中的__proto__)指向哪里呢;

对象的构造函数是 Object()。

当我们需要创建的一个对象的时候,是不是可以 通过

const obj = Object();

这种方式来构建一个对象。

所以,原型对象的隐式原型(xxx.prototype.proto)指向的就是对象构造函数的显式原型(Object.prototype);

而这一个逐级向上寻找的过程被称为原型链。

举个例子

Object.prototype.result = "遗憾";

const Person(name,love) {
    this.name = name;
    this.she = love;
}

const per = new Person("我","她");

per.result === "遗憾"    //true

上面这个例子中,per本身没有result属性,Person的显示原型上面也没有result属性,但是Object的显示原型上有这个属性。

per在访问result这个属性的时候会先在本身找

本身没有,会访问自己的__proto__(自己的隐式原型指向自己构造函数的显示原型)去自己构造函数的显示原型上找(也就是Person.prototype);

自己构造函数的显示原型(也就是Person.prototype)上没有就会访问构造函数的显示原型中的隐式原型(也就是Person.prototype.proto)从而找到Object的显式原型(Object.prototype)

最后在Object.prototype中找到了 result 属性,从而返回result。

如果一直找到Object.prototype仍未寻找到想要的值,会返回null;

Object.prototype.__proto__ === null  //true

原型对象的隐式原型指向其构造函数的显式原型。但是因为Object.显式原型已经到头了。没有更上一层了。所以Object.prototype.__proto__指向null

proto.png

欢迎技术沟通,摸鱼聊天~

备注来自掘金~

wx:XXF1096032096