ES6 Class

本文是记录ES6文档的Class章节的读书笔记,建议先阅读文档

Points

  • Es6的class可以看做只是一个语法糖
  • 通过Object.assign方法可以一次向类添加多个方法
  • 与ES5的行为不同的是,Class内部所有定义的方法都是不可枚举的
  • 类的属性名,可以采用表达式
  • 一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加
  • constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
  • S5的行为一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)
  • 与ES5的行为一样,类的所有实例共享一个原型对象
  • 与ES5行为完全不同的是,Class不存在变量提升(hoist)
  • 与函数一样,类也可以使用表达式的形式定义,可以写出立即执行的Class
  • ES6不提供私有方法,只能通过变通方法模拟实现
  • Class中this的指向
  • ES5继承机制 VS ES6继承机制
  • 类的prototype属性和__proto__属性
  • 子类的Super使用,必须显式指定是作为函数、还是作为对象使用,否则会报错
  • Class的取值函数(getter)和存值函数(setter)
  • Class的Generator方法
  • Class的静态方法
  • Class的静态属性和实例属性
  • Mixin模式的实现

Es6的class可以看做只是一个语法糖

//传统方法是通过构造函数,定义并生成新对象
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var p = new Point(1, 2);

通过Object.assign方法可以一次向类添加多个方法

由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法。

class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

与ES5的行为不同的是,Class内部所有定义的方法都是不可枚举的

//ES5
var Point = function (x, y) {
  // ...
};

Point.prototype.toString = function() {
  // ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
//ES6
class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

类的属性名,可以采用表达式

let methodName = "getArea";
class Square{
  constructor(length) {
    // ...
  }

  [methodName]() {
    // ...
  }
}

constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象

class Foo {
  constructor() {
    return Object.create(null);
  }
}

new Foo() instanceof Foo
// false

S5的行为一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)

//定义类
class Point {

  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }

}

var point = new Point(2, 3);

point.toString() // (2, 3)

point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true

上面代码中,x和y都是实例对象point自身的属性(因为定义在this变量上),所以hasOwnProperty方法返回true,而toString是原型对象的属性(因为定义在Point类上),所以hasOwnProperty方法返回false。这些都与ES5的行为保持一致。

与ES5的行为一样,类的所有实例共享一个原型对象

var p1 = new Point(2,3);
var p2 = new Point(3,2);

p1.__proto__ === p2.__proto__
//true

上面代码中,p1和p2都是Point的实例,它们的原型都是Point.prototype,所以__proto__属性是相等的。

上一篇:js es6语法 class类 class继承 super关键字


下一篇:js设置昨天的日期