18910140161

JavaScript的原型和继承解释

顺晟科技

2021-07-25 09:39:02

327

论JS的原型和继承相关概念

ES6之后,JavaScript可以通过类、扩展等语法糖实现面向对象的编写。但是,必须理解以前的原型对象。如果看了文章,记不清楚,自己总结一下。

构造器

在谈原型之前,有必要先了解一下之前的面向对象写作。JavaScript对象是通过构造函数实例获得的:

函数Fo(msg){ 0

this.msg=msg

}

Person是构造函数,个字母通常是大写的。并且有两个形式参数:姓名和性别,它们被分配给这个对象。

此时,您可以通过操作new获得Person的一个实例:

const f=new Foo('Hello ')

console.log(f.msg) //Hello

这里有一个问题,为什么msg可以通过实例对象人访问?下面我们就来说说新的操作。事实上,当new实例化构造函数时,以下操作是在内部完成的:

var obj={}

物体。__原型_ _ _=人.原型

人称呼叫

返回对象

上面看到了两个奇怪的东西,即__proto__和原型。这两个是什么?

原型对象和原型链

__proto__:每个实例对象都有这个属性,对应构造函数的原型函数;

原型:原型对象,每个构造函数都有。

从下图中,我们可以看出两者之间的关系:

从图中可以看出,实例对象的__proto__指向其构造函数的原型,而JavaScript在使用属性或方法时有一个特点,就是寻找当前实例对象中要调用的属性或方法,如果没有,就寻找实例对象的proto**(即寻找构造函数的原型对象),直到在顶层找到或达到null。**

从代码中,你可以看到它是完全相等的:

console . log(f . _ _ proto _ _===Fo . prototype)//true

F. _ _ proto _ _=fo。原型=fo。原型。_ _ proto _=对象。prototype=null,则形成一个链结构,称为原型链。

遗产

JavaScript的继承有两种情况,种是属性的继承,可以通过调用方法实现,第二种是方法的继承,需要通过原型链实现。看看代码:

函数Foo(msg){ 0

this.msg=msg

}

foo . prototype . printsmsg=function(){ 0

控制台.日志(this.msg)

}

函数Fo(消息,问候){ 0

Foo.call(这个,msg)

问候

}

Fo.prototype=new Foo()

Fo.prototype.constructor=Fo

fo . prototype . print greet=function(){ 0

console.log(this.greet)

}

const Fo=new Fo(‘你好’,‘你好吗?’)

console.log(fo)

打印此fo,您可以看到下图:

显然,greet属性和msg属性属于Fo实例对象,然后看看printMsg和printGreet方法:

此时printGreet在fo _ proto _上,即Fo.prototype

因为Fo.prototype指向Foo的实例对象,所以Fo.prototype实际上指向Foo的实例对象。

最后,您可以看到printMsg挂在Foo.prototype对象上。

因此可以看出,我们访问fo对象的属性时,是在实例对象本身上,可以直接访问;

当访问一个方法时,它是通过访问fo找到的。__proto__,即Fo.prototype,即Foo实例对象。根据原型链的特点,当对应的方法无法访问时,会在Foo实例对象的__proto__属性上找到,即Foo.prototype,从而实现方法继承。

摘要

其实JavaScript的对象是通过新的构造函数得到的,new的过程已经帮我们处理好了;

继承是通过原型链的特性实现的,将“子类”的原型指向“父类”的实例对象,这样在通过原型链进行搜索时,自然会从子类看向父类。

我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航