高血压专题网,内容丰富有趣,生活中的好帮手!
高血压专题网 > javascript 本地对象和内置对象_详解 JavaScript 面向对象

javascript 本地对象和内置对象_详解 JavaScript 面向对象

时间:2019-08-21 13:16:55

相关推荐

javascript 本地对象和内置对象_详解 JavaScript 面向对象

1. 概述

JavaScript面向对象比较难理解的点是类的继承。不管是es5写法还是es6写法,JavaScript继承的本质是原型链。具体可看我的上一篇文章:

田浩:详解原型、原型链、构造函、实例、new​

因为es6有专门的语法,写法很简单且容易理解,所以本文将着重介绍es5的实现继承不同方式及其原理。

再阅读本文之前,一定要注意区分几个名词:父类、子类、子类的实例。

2.类的声明和实例化:

/*** 类的声明*/var Animal = function () {this.name = 'Animal';};/*** es6中class的声明*/class Animal2 {constructor () {this.name = 'Animal2';}}/*** 实例化方式相同*/let dog = new Animal();let dog2 = new Animal2();

2. ES5中类的继承:

2.1 借助构造函数实现继承(部分继承)

function Parent1 () {this.name = 'parent1';}Parent1.prototype.say = function () {};// 不会被子类继承function Child1 () {Parent1.call(this);this.type = 'child1';}

原理:

核心在于:Parent1.call(this)

改变Parant1运行时的this的指向,指向子构造函数,所以父类中有的属性,子类中也有。

缺点:

父类原型链上的属性方法并没有被子类继承。 所以这种方式不能成为继承,只能叫做部分继承。

2.2 借助原型链实现继承

function Parent2 () {this.name = 'parent2';this.array = [1,2,3];}function Child2 () {this.type = 'child2';}Child2.prototype = new Parent2();

原理:

核心在于: Child2.prototype =new Parent2();

将Parent2的一个实例作为Child2的prototype。访问Child2的实例时候,实例可以通过__proto__访问Parent2中的属性。

缺点:

试想,如果Child2实例两个对象s1、s2,他们通过__proto__访问的父类上的属性实际上是同一个引用(s1.__proto__ === s2.__proto__)。这样,比如s1修改array,s2的array也会跟着变。这是我们所不想看到的。

2.3 组合方式

将上两种组合:

function Parent3 () {this.name = 'parent3';this.array = [1, 2, 3];}function Child3 () {Parent3.call(this); this.type = 'child3';}Child3.prototype = new Parent3();

原理:

核心在于: 将上两种方式结合。实际上,子类的实例中,Parent3上的属性会存在两份,一份在实例中,一份在实例的__proto__上:

缺点:

实例化子类的时候,父类执行了两次,且子类实例中存在冗余数据。这些都是没有必要的。

2.4 组合继承的优化1

function Parent4 () {this.name = 'parent4';this.play = [1, 2, 3];}function Child4 () {Parent4.call(this);this.type = 'child4';}Child4.prototype = Parent4.prototype;

原理:

核心在于: 将 Parent4的prototype直接赋给Child4.prototype。此时父类只执行一次。

缺点:

子类实例的constructor会指向父类:a的constructor会指向Parent4,不符合预期,无法区分这个实例是父类创造的还是子类创造的。当然这个缺点在2.3中也存在。原因是constructor属性来自原型对象中,上述方法子类的实例访问constructor 实际访问的事父类的prototype中的constructor。

2.5 组合继承的优化2

function Parent5 () {this.name = 'parent5';this.play = [1, 2, 3];}function Child5 () {Parent5.call(this);this.type = 'child5';}Child5.prototype = Object.create(Parent5.prototype);// 手动修改constructor指向,由于父类的prototype和子类的prototype已经隔离开,可以放心修改。Child5.prototype.constructor = Child5;

原理:

核心在于: Object.create(Parent5.prototype);

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

Object.create()​

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。