[转]JavaScript ES6 class指南

前言

EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民。但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的新特性。不过,它使代码的可读性变得更高,并且为今后版本里更多面向对象的新特性打下了基础

这样做的原因是为了保证向后兼容性。也就是,旧代码可以在不做任何hack的情况下,与新代码同时运行。

定义类

让我们回想一下在ES5中定义一个类的方式。通过不是很常用的Object.defineProperty方法,我可以定义一些只读的属性。

function Vehicle(make, year) {
Object.defineProperty(this, 'make', {
get: function() { return make; }
}); Object.defineProperty(this, 'year', {
get: function() { return year; }
});
} Vehicle.prototype.toString = function() {
return this.make + ' ' + this.year;
} var vehicle = new Vehicle('Toyota Corolla', 2009); console.log(vehicle.make); // Toyota Corolla
vehicle.make = 'Ford Mustang';
console.log(vehicle.toString()) // Toyota Corolla 2009

很简单,我们定义了一个有两个只读属性和一个自定义toString方法的Vehicle类。让我们在ES6中来做一样的事情:

class Vehicle {
constructor(make, year) {
this._make = make;
this._year = year;
} get make() {
return this._make;
} get year() {
return this._year;
} toString() {
return `${this.make} ${this.year}`;
}
} var vehicle = new Vehicle('Toyota Corolla', 2009); console.log(vehicle.make); // Toyota Corolla
vehicle.make = 'Ford Mustang';
console.log(vehicle.toString()) // Toyota Corolla 2009

类声明

在ES6中,有两个声明类的方式。第一种方法叫作 类声明,这也是我们在上述例子中使用的方式。

class Vehicle {
hello() {
console.log('nice to meet you');
}
}

有一个需要注意的地方是,类声明与函数声明不同,它不会被提升(hoisted)。例如,以下的代码工作正常:

console.log(helloWorld());

function helloWorld() {
return "Hello World";
}

但是,以下代码会抛出一个异常:

var vehicle = new Vehicle();

class Vehicle {
}

类表达式

另一个定义类的方式叫做 类表达式。它与函数表达式的运行方式完全一样。一个类表达式可以是具名的也可以是匿名的。

var Vehicle = class {
} var Vehicle = class VehicleClass {
constructor() {
// VehicleClass is only available inside the class itself
}
} console.log(VehicleClass); // throws an exception

静态方法

static关键字是ES6的另一个语法糖,它使静态方法声明也成为了一个一等公民。在ES5中,静态方法就像是构造函数的一个属性。

function Vehicle() {
// ...
} Vehicle.compare = function(a, b) {
// ...
}

在使用了新的static关键字后:

class Vehicle {
static compare(a, b) {
// ...
}
}

在底层,JavaScript所做的,也只是将这个方法添加为Vehicle构造函数的一个属性。值得注意的是,你也可以用同样的语法为类添加静态属性。

类继承

旧的原型继承有时看起来让人非常头疼。ES6中新的extends关键字解决了这个问题。在ES5,我们是这么做的:

function Motorcycle(make, year) {
Vehicle.apply(this, [make, year]);
} Motorcycle.prototype = Object.create(Vehicle.prototype, {
toString: function() {
return 'Motorcycle ' + this.make + ' ' + this.year;
}
}); Motorcycle.prototype.constructor = Motorcycle;

使用的新的extends关键字,看上去就清晰多了:

class Motorcycle extends Vehicle {
constructor(make, year) {
super(make, year);
} toString() {
return `Motorcycle ${this.make} ${this.year}`;
}
}

super关键字也可以用于静态方法:

class Vehicle {
static compare(a, b) {
// ...
}
} class Motorcycle extends Vehicle {
static compare(a, b) {
if (super.compare(a, b)) {
// ...
}
}
}

上一个例子也展示了新的super关键字的用法。当你想要调用父类的函数时,这个关键字就显得十分好用。

在想要调用父类的构造函数时,你可以简单地将super关键字视作一个函数使用,如super(make, year)。对于父类的其他函数,你可以将super视作一个对象,如super.toString()。例子:kk:super指向原型对象

class Motorcycle extends Vehicle {
toString() {
return 'Motorcycle ' + super.toString();
}
}

可被计算的方法名

当在class中声明属性时,定义属性名时,你可以使用表达式。这个语法特性在一些ORM类库中将会非常流行。例子:

function createInterface(name) {
return class {
['findBy' + name]() {
return 'Found by ' + name;
}
}
} const Interface = createInterface('Email');
const instance = new Interface(); console.log(instance.findByEmail());

最后

在当前,使用class关键字来声明类,而不使用原型,获得的仅仅是语法上的优势。但是,这个是一个适应新语法和新实践的好开始。JavaScript每天都在变得更好,并且通过class关键字,可以使各种工具更好得帮助你。

[转]JavaScript ES6 class指南的更多相关文章

  1. JavaScript ES6 class指南

    前言 EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的 ...

  2. javascript立体学习指南

    javascript立体学习指南第一章:首先了解javascript 首先,什么是javascript? JavaStrip出生于1995年,是一种文本脚本语言,成都装修公司是一种动态的.弱类型的.基 ...

  3. JavaScript编码规范指南

    前言 本文摘自Google JavaScript编码规范指南,截取了其中比较容易理解与遵循的点作为团队的JavaScript编码规范. JavaScript 语言规范 变量 声明变量必须加上 var  ...

  4. JavaScript 跳坑指南

    JavaScript 跳坑指南 坑0-String replace string的replace方法我们经常用,替换string中的某些字符,语法像这样子 string.replace(subStr/ ...

  5. 《JavaScript面向对象编程指南(第2版)》读书笔记(一)

    目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...

  6. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  7. JavaScript ES6中export及export default的区别

    相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...

  8. JavaScript ES6 新特性详解

    JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const ,  let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...

  9. JavaScript ES6 核心功能一览

    JavaScript 在过去几年里发生了很大的变化.这里介绍 12 个你马上就能用的新功能. JavaScript 历史 新的语言规范被称作 ECMAScript 6.也称为 ES6 或 ES2015 ...

随机推荐

  1. Control character in cookie value, consider BASE64 encoding your value-Cookie保存中文出错[转]

    项目当中用到cookie保存中文,但是会报如下错误: Control character in cookie value, consider BASE64 encoding your value 大概 ...

  2. 使用StackTrace堆栈跟踪记录详细日志(可获取行号)

    上一篇我们提到使用.NET自带的TraceSource实现简单的日志,具体请看<轻松背后的N+疲惫——系统日志>,这一篇注意想讲的是日志的详细记录,包含请求开始到结束的过程中调用的方法链以 ...

  3. SqlServer中代理作业实现总结

    今天弄SqlServer代理作业,弄了半天,把遇到的问题总结出来,主要是抨击一下Sql Server的Express版本.好了,看下面的正题. 首先,需要安装Sql Server Agent服务,该服 ...

  4. DEP受保护的问题(尤其是Outlook)

    We see this issue quite regularly as we use MAPI and lots of our users run our application on TS. Of ...

  5. thinkphp中神奇的create()方法

    正常的表单提交会把所有的表单数据提交上来 $data = $_POST; print_r($data);exit; 结果 Array ( [status] => 1 [comment] => ...

  6. [转]linux下IPTABLES配置详解

    如果你的IPTABLES基础知识还不了解,建议先去看看.开始配置我们来配置一个filter表的防火墙.(1)查看本机关于IPTABLES的设置情况[root@tp ~]# iptables -L -n ...

  7. CreateThread线程函数

    之前在一篇 基于TCP套接字实现的简单Demo   一文中用到了线程函数CreateThread()函数来 创建新的线程.下面以一个最简单的多线程例子来说明. C-代码如下: //最简单的创建多线程实 ...

  8. 安装oracle客户端(navicat for oracle)

    本文使用Navicat for Oracle工具连接oracle 安装的过程我就不在此赘述,跟一般软件的安装过程类似.下面主要讲解Navicat的配置. 1.启动该工具,出现如下的开始界面,单击“连接 ...

  9. http 中get和post

    1. http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html 浅谈HTTP中Get与Post的区别 2009-03-31 14:51 ...

  10. 深信服笔试题(网络project师售后)

    总共同拥有3到大题, 1选择 主要有ip地址计算.http协议.vrrp协议. 2.主要是linux填空题 a.linux显示全部系统载入模块____ b.写出linux的两个开机启动程序___.__ ...