当前位置:K88软件开发文章中心编程语言JavaScriptECMAScript → 文章内容

ECMAScript 6 Class

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:38:41

} * [Symbol.iterator]() { for (let arg of this.args) { yield arg; } }}for (let x of new Foo('hello', 'world')) { console.log(x);}// hello// world上面代码中,Foo类的Symbol.iterator方法前有一个星号,表示该方法是一个Generator函数。Symbol.iterator方法返回一个Foo类的默认遍历器,for...of循环会自动调用这个遍历器。Class的静态方法类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。class Foo { static classMethod() { return 'hello'; }}Foo.classMethod() // 'hello'var foo = new Foo();foo.classMethod()// TypeError: foo.classMethod is not a function上面代码中,Foo类的classMethod方法前有static关键字,表明该方法是一个静态方法,可以直接在Foo类上调用(Foo.classMethod()),而不是在Foo类的实例上调用。如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。父类的静态方法,可以被子类继承。class Foo { static classMethod() { return 'hello'; }}class Bar extends Foo {}Bar.classMethod(); // 'hello'上面代码中,父类Foo有一个静态方法,子类Bar可以调用这个方法。静态方法也是可以从super对象上调用的。class Foo { static classMethod() { return 'hello'; }}class Bar extends Foo { static classMethod() { return super.classMethod() + ', too'; }}Bar.classMethod();Class的静态属性和实例属性静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。class Foo {}Foo.prop = 1;Foo.prop // 1上面的写法为Foo类定义了一个静态属性prop。目前,只有这种写法可行,因为ES6明确规定,Class内部只有静态方法,没有静态属性。// 以下两种写法都无效class Foo { // 写法一 prop: 2 // 写法二 static prop: 2}Foo.prop // undefinedES7有一个静态属性的提案,目前Babel转码器支持。这个提案对实例属性和静态属性,都规定了新的写法。(1)类的实例属性类的实例属性可以用等式,写入类的定义之中。class MyClass { myProp = 42; constructor() { console.log(this.myProp); // 42 }}上面代码中,myProp就是MyClass的实例属性。在MyClass的实例上,可以读取这个属性。以前,我们定义实例属性,只能写在类的constructor方法里面。class ReactCounter extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; }}上面代码中,构造方法constructor里面,定义了this.state属性。有了新的写法以后,可以不在constructor方法里面定义。class ReactCounter extends React.Component { state = { count: 0 };}这种写法比以前更清晰。为了可读性的目的,对于那些在constructor里面已经定义的实例属性,新写法允许直接列出。class ReactCounter extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } state;}(2)类的静态属性类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。class MyClass { static myStaticProp = 42; constructor() { console.log(MyClass.myProp); // 42 }}同样的,这个新写法大大方便了静态属性的表达。// 老写法class Foo {}Foo.prop = 1;// 新写法class Foo { static prop = 1;}上面代码中,老写法的静态属性定义在类的外部。整个类生成以后,再生成静态属性。这样让人很容易忽略这个静态属性,也不符合相关代码应该放在一起的代码组织原则。另外,新写法是显式声明(declarative),而不是赋值处理,语义更好。new.target属性new是从构造函数生成实例的命令。ES6为new命令引入了一个new.target属性,(在构造函数中)返回new命令作用于的那个构造函数。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。function Person(name) { if (new.target !== undefined) { this.name = name; } else { throw new Error('必须使用new生成实例'); }}// 另一种写法function Person(name) { if (new.target === Person) { this.name = name; } else { throw new Error('必须使用new生成实例'); }}var person = new Person('张三'); // 正确var notAPerson = Person.call(person, '张三'); // 报错上面代码确保构造函数只能通过new命令调用。Class内部调用new.target,返回当前Class。class Rectangle { constructor(length, width) { console.log(new.target === Rectangle); this.length = length; this.width = width; }}var obj = new Rectangle(3, 4); // 输出 true需要注意的是,子类继承父类时,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上面代码中,new.target会返回子类。利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。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); // 正确上面代码中,Shape类不能被实例化,只能用于继承。注意,在函数外部,使用new.target会报错。Mixin模式的实现Mixin模式指的是,将多个类的接口“混入”(mix in)另一个类。它在ES6的实现如下。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); } }}上面代码的mix函数,可以将多个对象合成为一个类。使用的时候,只要继承这个类即可。class DistributedEdit extends mix(Loggable, Serializable) { // ...}

上一页  [1] [2] [3] [4] [5] 


ECMAScript 6 Class