原文:http://www.cli-nerd.com/2015/09/09/7-reasons-to-upgrade-to-node-v4-now.html
译者:@lizheming
前些日子 Node 4 终于发布了。作为 node.js 和 io.js 合并之后发布的第一个稳定版,Node 4 给我们带来了诸多 ES6 特性。你可以阅读这篇文章概览一下 ES6 的特性,本文将为你展示我们在 Node 4 中如何使用 ES6。
以前我们拼字符串的话会像下边这样写:
var message = [
'The quick brown fox',
'jumps over',
'the lazy dog'
].join('\n');
这段代码的作用是把字符串拼接成几句话。然而更极客的做法是像 multiline 一样利用注释来格式化字符串:
var multiline = require('multiline');
var message = multiline(function () {/*
The quick brown fox
jumps over
the lazy dog
*/});
好消息是,ES6 已经自带模板字符串语法了:
var message = `
The quick brown fox
jumps over
the lazy dog
`;
模板字符串语法还能插入字符串变量:
var name = 'Schroedinger';
// 别再这么写糟蹋自己了!
var message = 'Hello ' + name + ', how is your cat?';
var message = ['Hello ', name, ', how is your cat?'].join('');
var message = require('util').format('Hello %s, how is your cat?', name);
// 快使用模板字符串吧!
var message = `Hello ${name}, how is your cat?`;
点击这里去 MDN 查阅关于模板字符串的详细说明。
ES5 中我们定义一个类会这么写:
var Pet = function (name) {
this._name = name;
};
Pet.prototype.sayHello = function () {
console.log('*scratch*');
};
Object.defineProperty(Pet.prototype, 'name', {
get: function () {
return this._name;
}
});
var Cat = function (name) {
Pet.call(this, name);
};
require('util').inherits(Cat, Pet);
Cat.prototype.sayHello = function () {
Pet.prototype.sayHello.call(this);
console.log('miaaaauw');
};
怎么说呢,用原型链的写法可以实现效果,但是比起专门的类定义来说这么写总觉得有点怪,而且费时间。ES6 中为我们提供了类定义的语法糖:
class Pet {
constructor(name) {
this._name = name;
}
sayHello() {
console.log('*scratch*');
}
get name() {
return this._name;
}
}
class Cat extends Pet {
constructor(name) {
super(name);
}
sayHello() {
super.sayHello();
console.log('miaaaauw');
}
}
这样看起来就挺舒服了。点击这里了解更多。
函数内的 this
指向问题已经让无数程序员晕头转向了,我们经常可以看到为了获取到外部的this
指向我们不得不这么写:
Cat.prototype.notifyListeners = function () {
var self = this;
this._listeners.forEach(function (listener) {
self.notifyListener(listener);
});
};
Cat.prototype.notifyListeners = function () {
this._listeners.forEach(function (listener) {
this.notifyListener(listener);
}.bind(this));
};
ES6 中我们可以直接使用箭头函数语法让匿名函数的 this
指向所在的作用域:
Cat.prototype.notifyListeners = function () {
this._listeners.forEach((listener) => {
this.notifyListener(listener);
});
};
点击这里了解更多。
当你要使用对象的时候,你可以用非常简便的方法定义它:
var age = 10, name = 'Petsy', size = 32;
// 以前我们只能这么写
var cat = {
age: age,
name: name,
size: size
};
// ES6 中可以这么写了
var cat = {
age,
name,
size
};
另外,根据这个特性我们可以非常方便的给对象添加函数了。
以前我们只能依赖 bluebird
或者 Q
等库做 Promise 处理,现在我们可以使用原生的 Promise 函数了。原生 Promise 拥有以下几个 API:
var p1 = new Promise(function (resolve, reject) {});
var p2 = Promise.resolve(20);
var p3 = Promise.reject(new Error());
var p4 = Promise.all(p1, p2);
var p5 = Promise.race(p1, p2);
// and obviously
p1.then(() => {}).catch(() => {});
ES6 为字符串增加了很多新函数:
// 在许多场景下使用下面的函数会比用 `indexOf()` 要方便很多
name.startsWith('a')
name.endsWith('c');
name.includes('b');
// 重复 name 三次
name.repeat(3);
而且 ES6 还增强了对 unicode 字符的支持。
猜猜下面这段代码将会返回什么:
var x = 20;
(function () {
if (x === 20) {
var x = 30;
}
return x;
}()); // -> undefined
是的,由于 var x
声明提前导致返回的结果是 undefined
。现在你可以使用let
代替 var
语法,你将会得到一个不一样的结果:
let x = 20;
(function () {
if (x === 20) {
let x = 30;
}
return x;
}()); // -> 20
结果将返回 20。这个原因是因为 var
是函数作用域而let
是块级作用域,if
块体内定义的 let x
只在自己的块体中有效。你可以点击这里了解更多。
另外要说的是 Node 现在支持使用 const
关键字定义常量了,这样能保证你的变量值补丁:
var MY_CONST = 42; // 不要这样做啦...
const MY_CONST = 42; // 最好的做法是这样
MY_CONST = 10; // 如果上面是用 const 定义的这句将不生效
Node 4 携带了大量的 ES6 特性,我希望本文的几个例子能让你看到一些不错的地方从而升级到这个版本。当然还有很多其他的语言特征(像 maps/sets, symbols 和 generators),如果感兴趣可以去翻一下 官方的这篇文档。以上!
扫码关注w3ctech微信公众号
文章虽然叫做《升级 Node 4 的 7 个理由》但其实总结过来看就只有一个,那就是 Node 4 和 ES6 无缝结合!作为 node.js 和 io.js 合并后的第一个版本,我觉得它的背景意义要远超于它的代码意义(具体可搜索 node.js 和 io.js 的恩怨情仇)。当然,代码意义上 ES6 的整合不得不说是一大特性,内部的几个包括 V8 等组件的大升级也让我们更加快速开发(具体变更可参考 node.js changelog)。
@lizheming 怎么没有点赞的按钮,我要点赞!~^-^
@卢林 哈哈,谢谢支持,你可以点击标题下面的红心收藏应该就是赞了~~
共收到3条回复