class Foo {
constructor() {
return Object.create(null);
}
}
new Foo() instanceof Foo
// false
类的实例对象
类的调用的要加上new,类的所有实例共享一个原型对象。
var p1 = new Point(2,3);
var p2 = new Point(3,2);
p1.__proto__.printName = function () { return 'Oops' };
p1.printName() // "Oops"
p2.printName() // "Oops"
var p3 = new Point(4,2);
p3.printName() // "Oops"
this的指向
类的方法内部如果含有this,它默认指向类的实例。
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
logger.printName();
//Hello there
Class的继承
Class之间可以通过extends关键字实现继承。
class Point {
constructor(x,y,color){
this.x=x;
this.y=y;
this.color=color;
}
chooseColor(){
console.log('color:',this.color);
}
}
class ColorPoint extends Point {
constructor() {
super(1,2,'blue');
}
toString(){
return 'ColorPoint:'+super.color
}
}
var cp=new ColorPoint();
cp.chooseColor()
//VM2425:8 color: blue
var p1 = new Point(2, 3);
var p2 = new ColorPoint(2, 3, 'red');
p2.__proto__ === p1.__proto__ // false
p2.__proto__.__proto__ === p1.__proto__ // true
Class的取值函数(getter)和存值函数(setter)
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}
let inst = new MyClass();
inst.prop = 123;
// setter: 123
inst.prop
// 'getter'
prop属性有对应的存值函数和取值函数,因此赋值和读取行为都被自定义了。
Class 的 Generator 方法
class Foo {
constructor(...args) {
this.args = args;
}
* [Symbol.iterator]() {
for (let arg of this.args) {
yield arg;
}
}
}
for (let x of new Foo('hello', 'world')) {
console.log(x);
}
// hello
// world
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
ES6只用静态方法,没有静态属性。
new.target属性
new命令作用于的那个构造函数,子类继承父类时,new.target会返回子类。
class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
this.length = length;
this.width = width;
}
}
var obj = new Rectangle(3, 4); // 输出 true
Mixin模式的实现
Mixin模式指的是,将多个类的接口“混入”(mix in)另一个类。
function mix(...mixins) {
class Mix {}
for (let mixin of mixins) {
copyProperties(Mix, mixin);
copyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if ( key !== "constructor"
&& key !== "prototype"
&& key !== "name"
) {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
class DistributedEdit extends mix(Loggable, Serializable) {
// ...
}