javascript ES 6 class 详解
来源:互联网 发布:苹果c语言编程软件 编辑:程序博客网 时间:2024/06/08 19:19
javascript ES 6 class 详解
Introduction
上篇文章大致介绍了一些ES6的特性,以及如何在低版本浏览器中使用它们。本文是对class的详解。
译自Axel Rauschmayer的Classes in ECMAScript 6
另外,如果只是想测试ES6,可以到这个网站。
Overview
借助class 我们可以写出这样的代码:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return super.toString() + ' in ' + this.color; } } let cp = new ColorPoint(25, 8, 'green'); cp.toString(); // '(25, 8) in green' console.log(cp instanceof ColorPoint); // true console.log(cp instanceof Point); // true
Base classes
我们可以定义如下的class:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
我们可以像使用ES5标准中的constructor一样实例化class
> var p = new Point(25, 8); > p.toString() '(25, 8)'
实际上,class还是用function实现的,并没有为js创造一个全新的class体系。
> typeof Point 'function'
但是,与function相比,它是不能直接调用的,也就是说必须得new出来
> Point() TypeError: Classes can’t be function-called
另外,它不会像function一样会被hoisted(原因是语义阶段无法解析到extends的内容)
foo(); // works, because `foo` is hoisted function foo() {} new Foo(); // ReferenceError class Foo {}
function functionThatUsesBar() { new Bar(); } functionThatUsesBar(); // ReferenceError class Bar {} functionThatUsesBar(); // OK
与函数一样,class的定义表达式也有两种,声明形式、表达式形式。之前用的都是声明形式,以下是表达式式的:
const MyClass = class Me { getClassName() { return Me.name; } }; let inst = new MyClass(); console.log(inst.getClassName()); // Me console.log(Me.name); // ReferenceError: Me is not defined
Inside the body of a class definition
class定义体是只能包含方法,不能包含属性的(标准定义组织认为原型链中不应包含属性),属性被写在constructor中。以下是三种会用到的方法(constructor 、static method、 prototype method):
class Foo { constructor(prop) { this.prop = prop; } static staticMethod() { return 'classy'; } prototypeMethod() { return 'prototypical'; } } let foo = new Foo(123);
如下图([[Prototype]]代表着继承关系)当对象被new出来,拿的是Foo.prototype : Object分支,从而可以调prototype method
constructor,这个方法本身,代表了class
> Foo === Foo.prototype.constructor true
constructor有时被称为类构造器。相较于ES5,它可以调用父类的constructor(使用super())。
static methods。它们归属于类本身。
> typeof Foo.staticMethod 'function' > Foo.staticMethod() 'classy'
关于Getters and setters,它们的语法如下:
class MyClass { get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } } > let inst = new MyClass(); > inst.prop = 123; setter: 123 > inst.prop 'getter'
方法名是可以动态生成的
class Foo() { myMethod() {} } class Foo() { ['my'+'Method']() {} } const m = 'myMethod'; class Foo() { [m]() {} }
增加了迭代器的支持,需要给方法前面加一个*
class IterableArguments { constructor(...args) { this.args = args; } * [Symbol.iterator]() { for (let arg of this.args) { yield arg; } } } for (let x of new IterableArguments('hello', 'world')) { console.log(x); } // Output: // hello // world
Subclassing
通过extends,我们可以继承其它实现constructor的函数或对象。需要注意一下,constructor与非constructor调用父类方法的途径是不同的。
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // (A) this.color = color; } toString() { return super.toString() + ' in ' + this.color; // (B) } } > let cp = new ColorPoint(25, 8, 'green'); > cp.toString() '(25, 8) in green' > cp instanceof ColorPoint true > cp instanceof Point true
子类的原型就是它的父类
> Object.getPrototypeOf(ColorPoint) === Point true
所以,static method也被继承了
class Foo { static classMethod() { return 'hello'; } } class Bar extends Foo { } Bar.classMethod(); // 'hello'
static方法也是支持调用父类的。
class Foo { static classMethod() { return 'hello'; } } class Bar extends Foo { static classMethod() { return super.classMethod() + ', too'; } } Bar.classMethod(); // 'hello, too'
关于子类中使用构造器,需要注意的是,调用this之前,需要调用super()
class Foo {} class Bar extends Foo { constructor(num) { let tmp = num * 2; // OK this.num = num; // ReferenceError super(); this.num = num; // OK } }
constructors是可以被显示覆盖(override)的。
class Foo { constructor() { return Object.create(null); } } console.log(new Foo() instanceof Foo); // false
如果基类中不显示定义constructor,引擎会生成如下代码
constructor() {}
对于子类
constructor(...args) { super(...args); }
The details of classes
- 类名不能为eval 或者 arguments,不能有重复的类名,constructor不支持getter,setter。
- classes不能像函数一样调用。
- 原型方法不能用作构造器:
class C { m() {} } new C.prototype.m(); // TypeError
The details of subclassing
ES 6中,子类的使用方法如下:
class Point { constructor(x, y) { this.x = x; this.y = y; } ··· } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } ··· } let cp = new ColorPoint(25, 8, 'green');
原型链实现:
> const getProto = Object.getPrototypeOf.bind(Object);> getProto(Point) === Function.prototypetrue> getProto(function () {}) === Function.prototypetrue> getProto(Point.prototype) === Object.prototypetrue> getProto({}) === Object.prototypetrue
原文链接:http://www.cnblogs.com/E-WALKER/p/4796278.html
- javascript ES 6 class 详解
- Simulating class in JavaScript -- 6
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- es store详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- OpenGL ES入门详解
- JavaScript Class
- ES——类(Class)
- Class详解
- ActiveServices
- upload临时文件生存周期
- 检查读写权限
- NDK与Cygwin配置
- 组合练习1
- javascript ES 6 class 详解
- IO多路复用之poll总结
- 设计模式C++实现(8)——代理模式
- YUV学习之一
- 通过单例模式去加载可配置的常量
- C++程序设计语言练习11.4 算术运算符重载的类成员函数写法
- 正向代理、反向代理、透明代理
- android;layout_weight
- VIM ex