ES6 随笔 8-class

1.概述

ES5 constructor对象的语法糖,其中属性都是声明在prototype

class Point {
  constructor() {}
  toString() {}
  toValue() {}
}
// ES5 实现
Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

2.特点

类和模块的内部,默认严格模式
类内部声明的方法,均不可枚举
同函数声明,类也可以使用表达式声明
类声明不存在自动提升,保证父类先于子类声明
类中的this默认指向类实例,也会收到严格模式、运行时环境的影响(class 内部是严格模式,所以 this 实际指向的是undefined)

let methodName = 'getArea';    
const MyClass = class Me {    //类表达式
   [methodName]() {    //属性表达式
    // ...
  }
}  

3.存取器

class CustomHTMLElement {
  constructor(element) {
    this.element = element;
  }


  get html() {
    return this.element.innerHTML;
  }


  set html(value) {
    this.element.innerHTML = value;
  }}


var descriptor = Object.getOwnPropertyDescriptor(
  CustomHTMLElement.prototype, "html");


"get" in descriptor  // true
"set" in descriptor  // true

4.static 静态属性

静态方法可以与非静态方法重名。
父类的静态方法,可以被子类继承。
老写法的静态属性定义在类的外部。整个类生成以后,再生成静态属性。

5.实例属性

声明的位置:

//在constructor()方法里面的this上面
class IncreasingCounter {
  constructor() {
    this._count = 0;
  }
}
// 也可以定义在类的最顶层。
class IncreasingCounter {
  _count = 0;
}

6.私有属性

    不会被子类所继承
    symbol唯一性实现
    还有提案使用在属性名前面#表示
    运算符in可以表示是否属于该实例的私有属性
构造constructor中的特有属性new target确定构造的调用方式(若不是通过new 或 Reflect.construct()调用,则返回undefined),类名.call(arg...)等写法调用构造的方式将报错

7.构造器

constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。

8.class中的this

类的方法内部如果含有this,它默认指向类的实例。

只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。

防止this指向错误->构造中提前指定this引用

//将该方法的执行环境绑定到指定的this中执行
class Logger {
  constructor() {this.printName = this.printName.bind(this); }
}
// 显式声明this的get拦截方法
class Obj {
  constructor() {this.getThis = () => this; }
}
const myObj = new Obj();
myObj.getThis() === myObj // true
// Proxy 获取方法时候,自动绑定到this,实例篇幅较长,见文档

9.extend

extends ES6的继承方式,Es5通过修改原型链实现继承

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

10.super

super这个关键字,既可以当作函数使用,也可以当作对象使用。
super的时候,如果能清晰地表明super的数据类型(对象或是函数),就不会报错。

10.1 super作为函数调用时,代表父类的构造函数。

class A {
  constructor() {
    console.log(new.target.name);
  }
}
class B extends A {
  constructor() {
    super();
  }
}
new A() // A
new B() // B

super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例,因此super()在这里相当于A.prototype.constructor.call(this)。

10.2 作为父类对象

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。也就是说,实际上执行的是

super.print.call(this)。
class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() {
    super.print();
  }
}

let b = new B();
b.m() // 2

11.继承与原型对象的关系

Class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。

子类的原型与父类的关系:

Object.setPrototypeOf(B.prototype, A.prototype);
// 等同于
B.prototype.__proto__ = A.prototype;
Object.setPrototypeOf(B, A);
// 等同于
B.__proto__ = A;

这两条继承链,可以这样理解:作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

12.混入

Mixin 指的是多个对象合成一个新的对象,新对象具有各个组成成员的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值