ES6 class与ES5 function区别及联系

来源:互联网 发布:画图软件有哪些 编辑:程序博客网 时间:2024/05/23 13:23

关于构造器constructor

function定义的构造函数中,其prototype.constructor属性指向构造器自身
class定义的类中,constructor其实也相当于定义在prototype属性上

class Point {  constructor() {    // ...这了可以定义实例属性    this.a = 1;  }  toString() {    // ...  }  toValue() {    // ...  }}// 等同于Point.prototype = {  constructor() {},  toString() {},  toValue() {},};

重复定义

  • function会覆盖之前定义的方法
  • class会报错

原型或者类中方法的枚举

  • class中定义的方法不可用Object.keys(Point.prototype)枚举到
  • function构造器原型方法可被Object.keys(Point.prototype)枚举到,除过constructor
  • 所有原型方法属性都可用Object.getOwnPropertyNames(Point.prototype)访问到
class Point {  constructor(x, y) {    // ...  }  toString() {    // ...  }}Object.keys(Point.prototype)// []Object.getOwnPropertyNames(Point.prototype)// ["constructor","toString"]
var Point = function (x, y) {  // ...};Point.prototype.toString = function() {  // ...};Object.keys(Point.prototype)// ["toString"]Object.getOwnPropertyNames(Point.prototype)// ["constructor","toString"]

不管是class还是function,constructor属性默认不可枚举

都可通过实例的__proto__属性向原型添加方法

推荐使用Object.getPrototypeOf()获取实例原型后再添加方法

class没有变量提升

new Foo(); class Foo {}VM21735:1 Uncaught ReferenceError: Foo is not defined    at <anonymous>:1:1

class定义的类没有私有方法和私有属性

可以用symbol模拟

const bar = Symbol('bar');const snaf = Symbol('snaf');export default class myClass{  // 公有方法  foo(baz) {    this[bar](baz);  }  // 私有方法  [bar](baz) {//[bar]用方括号代表从表达式获取的属性名    return this[snaf] = baz;  }  // ...};

由于bar为symbol值,因此在外面不能当做函数使用。

this指向

class用类似于解构的方式获取原型上的方法

class Logger {constructor(){}  printName(name = 'there') {    this.print(`Hello ${name}`);  }  print(text) {    console.log(text);  }}const logger = new Logger();const { constructor,print,printName } = logger;

但是执行printName()时,他的this并不是指向当前实例,可在constructor中重新绑定:

constructor() {    this.printName = this.printName.bind(this);  }

class静态方法与静态属性

  • class定义的静态方法前加static关键字
  • 只能通过类名调用
  • 不能通过实例调用
  • 可与实例方法重名
  • 静态方法中的this指向类而非实例
  • 静态方法可被继承
  • 在子类中可通过super方法调用父类的静态方法
    class内部没有静态属性,只能在外面通过类名定义。

new.target

  1. new target属性指向当前的构造函数,不能在构造函数外部调用会报错,
function Person(name) {console.log(new.target);  if (new.target !== undefined) {    this.name = name;  } else {    throw new Error('必须使用new生成实例');  }}测试:Person(123)undefinedUncaught Error: 必须使用new生成实例

2.继承时new.target返回子类

class Rectangle {  constructor(length, width) {    console.log(new.target === Rectangle);    // ...  }}class Square extends Rectangle {  constructor(length) {    super(length, length);  }}var obj = new Square(3); // 输出 false

可构造不能被实例化的类,只能通过继承发挥作用:

class Shape {  constructor() {    if (new.target === Shape) {      throw new Error('本类不能实例化');    }  }}class Rectangle extends Shape {  constructor(length, width) {    super();    // ...  }}var x = new Shape();  // 报错var y = new Rectangle(3, 4);  // 正确
原创粉丝点击