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
上面两个例子中定义的类有一个不同的地方。我们为了享受新的get
语法带来的好处,所以只是将make
和year
定义成了普通的属性。这使它们可以被外部所改变。如果你确实需要一个严格的私有属性,还是请继续使用defineProperty
。
类声明
在ES6中,有两个声明类的方式。第一种方法叫作 类声明,这也是我们在上述例子中使用的方式。
class Vehicle() {
}
有一个需要注意的地方是,类声明与函数声明不同,它不会被提升(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 {
static compare(a, b) {
if (super.compare(a, b)) {
// ...
}
}
}
super关键字
上一个例子也展示了新的super
关键字的用法。当你想要调用父类的函数时,这个关键字就显得十分好用。
在想要调用父类的构造函数时,你可以简单地将super
关键字视作一个函数使用,如super(make, year)
。对于父类的其他函数,你可以将super
视作一个对象,如super.toString()
。例子:
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
关键字,可以使各种工具更好得帮助你。
原文地址
https://strongloop.com/strongblog/an-introduction-to-javascript-es6-classes/
JavaScript ES6 class指南的更多相关文章
- [转]JavaScript ES6 class指南
[转]JavaScript ES6 class指南 前言 EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建 ...
- javascript立体学习指南
javascript立体学习指南第一章:首先了解javascript 首先,什么是javascript? JavaStrip出生于1995年,是一种文本脚本语言,成都装修公司是一种动态的.弱类型的.基 ...
- JavaScript编码规范指南
前言 本文摘自Google JavaScript编码规范指南,截取了其中比较容易理解与遵循的点作为团队的JavaScript编码规范. JavaScript 语言规范 变量 声明变量必须加上 var ...
- JavaScript 跳坑指南
JavaScript 跳坑指南 坑0-String replace string的replace方法我们经常用,替换string中的某些字符,语法像这样子 string.replace(subStr/ ...
- 《JavaScript面向对象编程指南(第2版)》读书笔记(一)
目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...
- 《JavaScript面向对象编程指南(第2版)》读书笔记(二)
<JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...
- JavaScript ES6中export及export default的区别
相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...
- JavaScript ES6 新特性详解
JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const , let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...
- JavaScript ES6 核心功能一览
JavaScript 在过去几年里发生了很大的变化.这里介绍 12 个你马上就能用的新功能. JavaScript 历史 新的语言规范被称作 ECMAScript 6.也称为 ES6 或 ES2015 ...
随机推荐
- iOS弹窗UIAlertAction用法
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"确认" message:@&quo ...
- 《SaltStack技术入门与实践》—— Peer
Peer 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Peer组件是SaltStack中Minion向Master发布任务的一个组件,使用Peer ...
- 【NOIP2016提高A组模拟8.19】(雅礼联考day2)总结
第一题又有gcd,又有xor,本来想直接弃疗,不过后来想到了个水法: 当两个相邻的数满足条件时,那么他们的倍数也可能满足条件.然后没打,只打了个暴力. 正解就是各种结论,各种定理搞搞. 第二题,想都不 ...
- mysql——二级索引(辅助索引)
二级索引:叶子节点中存储主键值,每次查找数据时,根据索引找到叶子节点中的主键值,根据主键值再到聚簇索引中得到完整的一行记录. 问题: 1.相比于叶子节点中存储行指针,二级索引存储主键值会占用更多的空间 ...
- LDA终极分析
http://www.cnblogs.com/pinard/p/6867828.html http://www.52nlp.cn/lda-math-mcmc-和-gibbs-sampling2 htt ...
- Android字体设置,Roboto字体使用
一.自定义字体 1.android Typeface使用TTF字体文件设置字体 我们可以在程序中放入ttf字体文件,在程序中使用Typeface设置字体.第一步,在assets目录下新建fonts目录 ...
- Linux vi/vim and linux yum 命令
Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主 ...
- 新年第一发--HDU1848--Fibonacci again and again(SG函数)
Problem Description 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1)=1;F(2)=2;F(n)=F(n-1)+F(n-2 ...
- 20165220课程设计个人报告——Part4-Cortex M4模块
个人报告: 20165220 葛宇豪 1.个人贡献 a.实验环境搭建 b.代码分析与理解 2.设计中遇到的问题以及解决方案 问题1:mdk5每次编译之前都会直接闪退 刚开始以为是环境问题,后来上网查资 ...
- JSP 不能解析EL表达式的解决办法
原文地址:http://www.jb51.net/article/30791.htm 原因是:在默认情况下,Servlet 2.4 / JSP 2.0支持 EL 表达式. 解决的办法有两种: 1.修改 ...