首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

前端开发面向对象基础难点:如何理解JavaScript原型?

之前有讲过一次JavaScript原型和原型链的内容了,但是有很多同学和李老师说不好理解,今天重新整理了一下,结合一些案例,来专门讲一下原型。

我们为什么需要原型?什么是原型?

传统构造函数存在问题

很多时候,我们都喜欢使用传统的构造函数,然后使用new的方式来创建对象,但是这种方式是又点问题的。

举个例子:

通过自定义构造函数的方式,创建小狗对象:

给大家画个图理解一下对象实例化的过程:

在使用new关键字,每次创建一个对象的时候,都会在内存开辟一个新的空间,我们从上图可以看出,每只创建的小狗有一个say方法,这个方法都是独立的,但是功能完全相同。随着创建小狗的数量增多,造成内存的浪费就更多,这就是我们需要解决的问题。

为了避免内存的浪费,我们想要的其实是下图的效果:

解决方法:

这里最好的办法就是将函数体放在构造函数之外,在构造函数中只需要引用该函数即可。

看到这里,很多小伙伴就觉得,就这样换一下函数位置就可以解决问题了,也不算很难呀,也用不上原型呀。

但是其实这样写依然存在问题:

全局变量增多,会增加引入框架命名冲突的风险

代码结构混乱,会变得难以维护

在这样看,想解决上面的问题,就需要用到构造函数的原型概念了

原型的概念

prototype:原型。每个构造函数在创建出来的时候系统会自动给这个构造函数创建

并且关联一个空的对象。这个空的对象,就叫做原型。

关键点理解:

每一个由构造函数创建出来的对象,都会默认的和构造函数的原型关联;

当使用一个方法进行属性或者方法访问的时候,会先在当前对象内查找该属性和方法,如果当前对象内未找到,就会去跟它关联的原型对象内进行查找;

也就是说,在原型中定义的方法跟属性,会被这个构造函数创建出来的对象所共享;

访问原型的方式:

构造函数名.prototype。

画个图大家好理解一点:

示例代码:

给构造函数的原型添加方法

画个图理解:

在构造函数的原型中可以存放所有对象共享的数据,这样可以避免多次创建对象浪费内存空间的问题。

原型的使用

1、使用对象的动态特性

使用对象的动态属性,其实就是直接使用prototype为原型添加属性或者方法。

2、直接替换原型对象

每次构造函数创建出来的时候,都会关联一个空对象,我们可以用一个对象替换掉这个空对象。

注意:

使用原型的时候,有几个注意点需要注意一下,我们通过几个案例来了解一下。

1.使用对象.属性名去获取对象属性的时候,会先在自身中进行查找,如果没有,就去原型中查找;

2.使用对象.属性名去设置对象属性的时候,只会在自身进行查找,如果有,就修改,如果没有,就添加;

注意:一般情况下,不会将属性放在原型中,只会将方法放在原型中;

3.在替换原型的时候,替换之前创建的对象,和替换之后创建的对象的原型不一致!!!

画个图理解下:

图中可以看出,实例出来的h1对象指向的原型中,只有say()方法,并没有kill()方法,所以h1.kill()会报错。同理,h2.say()也会报错。

__proto__属性

在js中以_开头的属性名为js的私有属性,以__开头的属性名为非标准属性。__proto__是一个非标准属性,最早由firefox提出来。

1、构造函数的 prototype 属性

之前我们访问构造函数原型对象的时候,使用的是prototype属性:

在之前我们是无法通过构造函数new出来的对象访问原型的:

2、实例对象的 __proto__ 属性

__proto__属性最早是火狐浏览器引入的,用以通过实例对象来访问原型,这个属性在早期是非标准的属性,有了__proto__属性,就可以通过构造函数创建出来的对象直接访问原型。

如图所示:

3、__proto__属性的用途

可以用来访问原型;

在实际开发中除非有特殊的需求,不要轻易的使用实例对象的__proto__属性去修改原型的属性或方法;

在调试过程中,可以轻易的查看原型的成员;

由于兼容性问题,不推荐使用。

constuctor属性

constructor:构造函数,原型的constructor属性指向的是和原型关联的构造函数。

示例代码:

画个图理解:

获取复杂类型的数据类型:

在一个的函数中,有个返回值name,它表示的是当前函数的函数名;

其实JavaScript原型的运用更多是在面向对象编程的继承上,那在继承的时候我们具体要怎么使用呢?我们下次继续讲解!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20191211A0O8X900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券