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.prototype
true
> getProto(function () {}) === Function.prototype
true
> getProto(Point.prototype) === Object.prototype
true
> getProto({}) === Object.prototype
true
javascript ES 6 class 详解的更多相关文章
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- (转)javascript中event对象详解
原文:http://jiajiale.iteye.com/blog/195906 javascript中event对象详解 博客分类: javaScript JavaScriptCS ...
- Javascript 异步加载详解
Javascript 异步加载详解 本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy ...
- 【JavaScript中的this详解】
前言 this用法说难不难,有时候函数调用时,往往会搞不清楚this指向谁?那么,关于this的用法,你知道多少呢? 下面我来给大家整理一下关于this的详细分析,希望对大家有所帮助! this指向的 ...
- JavaScript中的this详解
前言 this用法说难不难,有时候函数调用时,往往会搞不清楚this指向谁?那么,关于this的用法,你知道多少呢? 下面我来给大家整理一下关于this的详细分析,希望对大家有所帮助! this指向的 ...
- Javascript中prototype属性详解 (存)
Javascript中prototype属性详解 在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不 ...
- Javascript常用的设计模式详解
Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...
- JavaScript 各种遍历方式详解及总结
JavaScript 各种遍历方式详解 在$.each中想要终止循环,但是它没有continue或者break这样的终止方式,所以尝试使用return来进行终止,但是发现并没有跳出循环.为了搞清楚js ...
- JavaScript进阶内容——DOM详解
JavaScript进阶内容--DOM详解 当我们已经熟练掌握JavaScript的语法之后,我们就该进入更深层次的学习了 首先我们思考一下:JavaScript是用来做什么的? JavaScript ...
随机推荐
- C++中对类的提前引用声明注意事项
//或许,友元是VC++6.0心里永远的痛,对于这个BUG我一直很介意.//注:这个程序在VC++6.0里是行不通的,在VS2008里是可以的.#include <iostream> #i ...
- 修改SO
1.如果在jni中定义的是int型的数据,比如: JNIEXPORT jint JNICALL Java_com_ggndktest1_JniGg_getCoin (JNIEnv * env, job ...
- 动态调试Android程序
最近好几天来一直在看动态调试.首先是这一篇(http://www.52pojie.cn/forum.php?mod=viewthread&tid=293648)里面介绍了多种IDA动态调试的情 ...
- Tutte矩阵求一般图最大匹配
[集训队2017论文集] 一张无向图的Tutte矩阵为 其中xi,j为一个random的值. Tutte矩阵的秩(一定为偶数)/2 就是这张图的最大匹配. 原理大概就是: 一个图有完美匹配,则det( ...
- C语言之fileno()函数--获取已经打开的文件的文件描述符(小技巧)
open函数相关的: /* open 是系统调用 返回的是文件句柄*/ #include <sys/stat.h> #include <fcntl.h> int open(c ...
- Win10设置vs2010总是以管理员身份运行
有的项目用vs打开后直接运行总是要求提升权限,如下图 1.第一步(这样的方式只能是先运行vs,然后再打开项目,这样才是以管理员的身份运行的.但是如果是通过sln文件的快捷方式打开的,却不是 ...
- Boost-ioservices介绍
IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service i ...
- eclipse编辑窗口不见了(打开左边的java、xml文件,中间不会显示代码)
转自:https://blog.csdn.net/u012062810/article/details/46729779?utm_source=blogxgwz4 1. windows-->re ...
- Unity4.0配置
关于Unity4.0的使用: 一 安装Unity 在程序包管理器控制台输入命令:Istall-Pckage unity.mvc安装后会在App_Start中生成UnityConfig.cs 和Unit ...
- Lightoj1028 【数学-乘法原理】
题意: 给你一个数,问你有多少种进制对n的表示,存在后导零: 比如30:用3进制表示: 1010 思路: 我们发现,就是一个数的约数就能对n表示最后存在后导零: 计算[2 ,n]之间的n的约数个数. ...