全面解析JavaScript的对象创建和继承

原文链接

摘要: 阿里巴巴前端工程师逸翾对JavaScript中的对象进行了详细讲解。首先从理解对象谈起,说明了对象中的两个关键点key和prototype,其次介绍了对创建对象的三种方式,包括字面量、构造函数、Object.create和class person,最后对JavaScript的继承进行了详细解析。

阿里巴巴前端工程师逸翾对JavaScript中的对象进行了详细讲解。首先从理解对象谈起,说明了对象中的两个关键点key和prototype,其次介绍了对创建对象的三种方式,包括字面量、构造函数、Object.create和class person,最后对JavaScript的继承进行了详细解析。

数十款阿里云产品限时折扣中,赶快点击这里,领券开始云上实践吧!

直播视频精彩回顾

以下是精彩视频内容整理:

理解对象

对象是无序属性的集合,其属性可以包含基本值、对象或者函数,对象的每个属性或者方法都有一个Key,而每个名字都映射到一个Value。

af6cd52d62adb4ebcf38a74d7aa696939c457487

对象结构中比较关键的两个点是key和prototype,key有自己的数据属性,比如writable、value以及设置或读取key值的方法等;prototype是JavaScript与其它语言最大不同的地方,继承主要是通过原型特性来实现的。如图所示,定义一个对象,在原型上绑定了一个key,这个key打印出“say hi”。

创建对象

在日常工作中常用的JavaScript创建对象的常用方式有很多,JavaScript是怎样创建对象的呢?

848a9c11885bcf207eb033fb17510be16ee4807c

最简单的方式是直接用字面量创建,定义一个变量,变量中有key-value,value可以是函数、可以是其它对象,能够定义出一个对象,打印出来如图的三个key(action、name和son),son中又有两个key,_proto_叫做隐式原型。

72ca12e77fbac56d1ccf4ce5f723051dc2f4a693

创建对象还有一种方式就是通过构造函数来创建,创建对象和继承关系很紧密。如图所示,创建一个构造函数person,有两个构造属性name和age,创建对象person1和person2,最后生成打印出来。Person1和person2这两个方法做的事情是完全相同的,浪费了资源,通过原型方式,让它们共用同一个方法,person1的隐式原型指向了person原型,person原型的构造函数是person,person指向person原型。

a5acee5954a39e170a473b36baa65c414252bdd8

我们还可以通过Object.create创建对象,Object.create相当于Object.prototype的一个语法糖,可以节省很多资源,只生成了中转对象,所有对象都会指向Object.prototype,Object.prototype指向null。

3fa368721109ca192bd521651d07d85b49f212e0

在ES6中出现什么样的创建对象方式呢?创建一个简单方法即是class person,如图所示。ES6中的class可以看作构造函数的另一种写法;构造函数的prototype属性,在ES6的“class”上面继续存在;class中定义的方法实际上也是挂载到原型上,而static静态属性则是挂载到构造函数本身上;class中定义的方法默认是不可枚举的。

JavaScript中的继承

JavaScript中最简单的继承是从构造函数通过new命令生成实例,比如:

function Dog(name){

this.name = name;

}

Var bigdog = new Dog(‘金毛’);

Console.log(biglog.name);

金毛;

Bindog直接继承了Dog的属性,打印出bindog在父类中的key,这种方法的缺点是每一个实例对象都有自己的属性和副本,不仅无法共享属性和方法,而且造成极大浪费资源。

0efd7f05e8eeb1bc0fa24d6898f0405b3a5e03bf

在ES6之前,最通用的方式是引入prototype属性,通过原型链实现继承,这也是最复杂的实现继承方式。prototype属性包含一个对象(prototype对象),所有实例对象需要共享的属性和方法,都放在这个对象里面,不需要共享的属性和方法,就放在构造函数里。如图所示,首先定义了supertype,在supertype的原型上挂载了一个方法getsupervalue,它会返回supertype的property属性。接着又定义了另外一个构造函数subtype,它的subproperty属性为false,使得supertype.prototype等于new supertype,supertype的隐式原型指向supertype的原型,supertype的原型对象构造函数是supertype,supertype的proto指向supertype的原型对象。然后将subtype的原型属性挂载getsubvalue的方法,此处原理与上面supertype一样。然后又实例化subtype对象,instance从supertype这里继承来了getsupervalue方法。此时,subtype prototype指向了subtype原型对象,instance隐式原型指向了subtype原型。

2633b5ed73acb97ff8732e6fec83a81f0f1449bd

在ES6中引入了extends关键字,但extends其实也是ES6众多语法糖之一而已,其本质仍是原型链,只是看起来清晰方便了很多。

ES5先创建子类的实例对象,ES6先创建父类的实例对象,然后再通过子类的构造函数修改this。如图所示,左侧代码中两个class中,stu继承了person全部的属性和方法,person中有一个构造函数和一个方法,stu也有自己的构造函数和方法,其中super关键字可以当作函数使用,代表父类的构造函数,继承父类name的属性,super也可以当作对象使用,指向父类的原型对象。

本文由云栖志愿小组毛鹤整理,编辑百见

猜你喜欢

转载自blog.csdn.net/weixin_40581980/article/details/81666575