七个升级到 Node.js V4.0 的理由
距离 Node.js 4.0 版本的发布已经有一段时间了,这是 io.js 与 Node.js 合并后的第一个稳定版,上一个 Node 版本还是 V0.12.7
呢!新的版本使用了 ES6,下面就介绍一下几个升级的理由。
1,模板字符串(Template Strings)
至于什么是模板字符串,请移步到这里 ,简单理解就是可以在字符串里包含语法。在之前的 Javascript 里,如果你想创建一个多行文本的字符串,也许你会使用下列方法:
var message = [
'The quick brown fox',
'jumps over',
'the lazy dog'
].join('\n');
这种方法虽然可以生效,但是毕竟有点奇技淫巧的味道,而且不适用于大量文本。但是在 ES6 中自带了输出多行文本的方法,既使用反撇号 ` ,不知道的可以在键盘上找好,一般是在键盘 1 左侧。以下是实用 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);
但是使用 ES6 你可以这样:
var message = `Hello ${name}, how is your cat?`;
怎么样?很任性吧!!!
2,类(Classes)
在之前的 Javascript 里,严格上说,是没有“类”这一概念的,因为它不能像 PHP 一样直接通过 Class 定义,而实现方法只能通过构造函数和原型,像下面:
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 的概念。如下:
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');
}
}
如果你懂得 PHP 或者其它有 Class 的语言,那么就会很熟悉这种写法了。如想了解更多关于 ES6 的 Class 请移步:这里。
3,箭头函数(Arrow Functions)
如果对 Javascript 掌握不是很好的朋友,也许会觉得 JS 里的 this 到底是指向哪里,很没把握,而且容易引起混乱。而箭头函数的概念,首先它是一个匿名函数,是简写的函数表达式,重要一点是它可以指定 this 值。语法如下:
([param] [, param]) => {
statements
}
param => expression 箭头左边是若干个参数,如果没有参数需要使用 () 来表示,如果只有一个参数,那么括号可以省略,比如:foo => 1。下面看一个例子:
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
如果把它拆成传统方式,则是:
var simple = function (a) {
if (a > 15) {
return 15;
} else {
return a;
}
}
关于箭头函数的 this 部分,传统方式:
Cat.prototype.notifyListeners = function () {
var self = this;
this._listeners.forEach(function (listener) {
self.notifyListener(listener);
});
};
使用箭头函数:
Cat.prototype.notifyListeners = function () {
this._listeners.forEach((listener) => {
this.notifyListener(listener);
});
};
4,对象字面量(Object Literals)
传统方式:
var age = 10, name = 'Petsy', size = 32;
var cat = {
age: age,
name: name,
size: size
};
用 ES6 方式:
var cat = {
age,
name,
size
};
两者输出的对象 cat 是一样的。
5,Promises 形式
Javascript 中 Promises 这个词在中文里不能翻译成 “承若”,而应该是普罗米修斯,意指有先见之明的意思。在 ES6 中已经有提供原生方法了,而不需要去模拟。
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(() => {});
6,字符串新方法
// replace `indexOf()` in a number of cases
name.startsWith('a')
name.endsWith('c');
name.includes('b');
// repeat the string three times
name.repeat(3);
7,let 和 const
先看下面这段代码:
var x = 20;
(function () {
if (x === 20) {
var x = 30;
}
return x;
}()); // -> undefined
至于为什么会返回 undefined 无需解释了,但是把 var 换成 let 会返回 20 :)
let x = 20;
(function () {
if (x === 20) {
let x = 30;
}
return x;
}()); // -> 20
var 与 let 这两者的区别是,let 允许把变量的作用域限制在块级域中。与 var 不同处是:var 申明变量要么是全局的,要么是函数级的,而无法是块级的。
除此之外,Node.js 还支持 const ,声明的是一个只读常量,不能重新赋值,如果声明时没有赋值,则一直是 undefined。
由于 Node.js 是运行在服务器的,无需担心浏览器之间的兼容问题,所以建议升级,享受新方法带来的便捷。