ECMAScript 6中类继承解析(附示例)

如果下载的源码需要作者授权,请更换源码。本站免费分享资源不会增加授权

本篇文章给大家带来的内容是关于ECMAScript 6中类继承解析(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

类继承

看类继承前,先回顾构造函数怎么实现对象的继承的

        function F() {             this.a = 1;         }         function Son() {             F.call(this);         }          function inherit(S, F) {             S.prototype = Object.create(F.prototype);             S.prototype.constructor = S;         }         inherit(Son, F);         let son = new Son();

它实现了哪几个功能:

继承F的this属性也就是F实例对象的属性

Son.prototype.__proto__ === F.prototype 实现了上下辈分的继承

son.constructor让son认祖归宗

同样类继承也是如此

用来extends和super关键字,看一个简单的继承

        class A {             constructor() {                 this.a = 1;             }         }         class B extends A {             constructor() {                 super();                 this.b = 2;             }             m() {              }         }         let b = new B();

同样实现了那三点基本功能

B {a: 1, b: 2} b.__proto__  == B.prototype b.__proto__.__proto__ === A.prototype b.constructor === B

我认为:关键字extends实现了原型的继承,以及constructor的修正;关键字super实现了父类this的继承,这里的super相当于A.prototype.constructor.call(this)

注意点

写了constructor,就必须在里面写super,不然new子类实例对象会报错;要么都不写;其次子类的中constructor中的this属性必须写在super后面

1.ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this
2.因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实 例属性和方法。如果不调用super方法,子类就得不到this对象。

        class B extends A {             constructor() {    //要么都不写,new时默认会自动生成                 super();                 this.b = 2;    //写在super后面             }              m() {              }         }

super的各种指向问题

super作为函数,只能放在子类的constructor中,指向A.prototype.constructor.call(this)

super作为对象,在子类普通方法中调用,super就是父类的原型也就是A.prototype;所以只能调用原型链上的方法,不能动用父类实例的方法和属性constructor{}中的不能调用

        class A {             constructor() {                  this.a = 1;             }             n() {                  return this;             }         }         class B extends A {             constructor() {                                  super();                 this.b = 2;                              }             m() {                 return super.n();             }         }         let b = new B();         b === b.m();

并且规定

在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。

所以上面return this 就是返回子类实例对象

super作为对象对属性赋值时
super相当于this,赋值属性也就成了子类实例的属性

class A {   constructor() {     this.x = 1;   } }  class B extends A {   constructor() {     super();     this.x = 2;     super.x = 3;     console.log(super.x); // undefined     console.log(this.x); // 3     console.log(super.valueOf() instanceof B);   //true   } }  let b = new B();

super作为对象,在静态方法中指向的是父类能调用父类的静态方法,如果方法内部有this则指向当前的子类
只有类才能调用类的静态方法

        class A {             constructor() {                  this.a = 1;             }             static n() {                  return this;             }         }         class B extends A {             constructor() {                                  super();                 this.b = 2;                              }             static m() {                 return super.n();             }         }         console.log(A.n() === A)   // true         console.log(B === B.m());  //true

由于对象总是继承其他对象的,所以可以在任意一个对象中,使用super关键字。

var obj = {   toString() {     return "MyObject: " + super.toString();   } }; Object.getPrototypeOf(obj).toString = function () {     return "这里super等于obj.__proto__"; } console.log(obj.toString());        //MyObject: 这里super等于obj.__proto__

类的prototype与__proto__

(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。

(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

类的继承模式

class A { }  class B { }  // B 的实例继承 A 的实例 Object.setPrototypeOf(B.prototype, A.prototype);  // B 继承 A 的静态属性 Object.setPrototypeOf(B, A);  const b = new B();

也是因为这种实现所以类能调用自己的静态方法

es6实现了原始构造函数的继承

之前Array.apply(this)this并不会塑造Array里面的内部结构,所以我们当我们用类数组对象引用数组方法时用null代替了
而es6用类实现它的继承,
代码摘自es6入门

class MyArray extends Array {   constructor(...args) {     super(...args);   } }  var arr = new MyArray(); arr[0] = 12; arr.length // 1  arr.length = 0; arr[0] // undefined

需要注意的是

ES6 改变了Object构造函数的行为,一旦发现Object方法不是通过new Object()这种形式调用,ES6 规定Object构造函数会忽略参数。

class NewObj extends Object{   constructor(){     super(...arguments);   } } var o = new NewObj({attr: true}); o.attr === true  // false

传入参数会无效的

本文由(壳先生)整理自网络,如转载请注明出处:https://www.mrshell.com;
本站发布的内容若侵犯到您的权益,请邮件联系 i@mrshell.com 删除,我们将及时处理!
===========================================================================

1. 本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行测试。
2. 本站资源仅供学习和交流使用,版权归资源原作者所有,请在下载后24小时之内自觉删除。
3. 不得使用于非法商业用途,商用请支持正版!不得违反国家法律,否则后果自负!
4. 若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与本站无关。
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!

=================================================================

壳先生 » ECMAScript 6中类继承解析(附示例)

发表评论

提供最优质的资源集合

立即查看 了解详情