ECMAScript6
前言
原文参考
伯乐在线-吴鹏煜
链接:http://web.jobbole.com/87140/
1.ES6中的默认参数
以前我们是这样来定义默认参数的:
var link = function(height, color, url) {
var height = height || 50
var color = color || 'red'
var url = url || 'http://azat.co'
}
但是这么定义有个问题,因为如果参数的值是0的时候,默认会成为’false’,这在赋值的时候就比较尴尬了。
现在ES6的写法是:
var link = function(height = 50, color = 'red', url = 'http://azat/co') {
}
2.ES6中的模板语法
ES5里,字符串的连接一般如下所示:
var str = aname + ' loves ' + 'bname';
var url = 'http://www.baidu.com:3000/' + pair_id
但是,如果需要连接的变量太多,或者字符串的结构较为复杂,就很容易出现错误,所以ES6引入了反引号包裹字符串。这样,在反引号包裹的字符串里,不再需要通过’+’来连接,而是直接用 aname或 {bname}来引用变量。
var str = `${aname} loves ${bname}`;
var url = `http://www.baidu.com:3000/${pair_id}`
3.ES6中的多行字符串
在ES5中,如果需要连接的字符串,一般会换行写,比如
var str = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.nt'
+ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
同样,在ES6中,只需要充分得利用好反引号“
var str = `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
you can you up, no can no bb`
4.ES6中的拆包表达式
ES5中有很多这样的应用场景,比如传递的参数是一个对象Object,需要将对象的属性值Object.data1和Object.data2赋值给data1和data2.
var data = $('body').data(),
data1 = data.data1
data2 = data.data2
但是在ES6中就简单了。
var { data1, data2 } = $('body').data()
数组中也可以使用。
5.ES6中改进的对象表达式
ES5中一个典型的对象如下:
var serviceBase = {port: 3000, url:'azat.co'},
getAccounts = function() {
return [1,2,3];
};
var accountServiceES5 = {
port: serviceBase.port,
url: serviceBase.url,
getAccounts: getAccounts,
toString: function() {
return JSON.stringify(this.valueOf())
},
getUrl: function() {
return 'http://' + this.url + ':' + this.port
},
valueOf_1_2_3: getAccounts()
}
可以用Object.create方法来让serviceBase称为accountServiceES6的prototype从而实现继承。
ES6改进:
var serviceBase = {port: 3000, url:'azat.co'},
getAccounts = function() {
return [1,2,3];
};
var accountServiceES5 = {
// port: serviceBase.port
// url: serviceBase.url
_proto_: serviceBase,
// getAccounts: getAccounts
getAccounts,
toString: function() {
return JSON.stringify(this.valueOf())
},
getUrl: function() {
return 'http://' + this.url + ':' + this.port
},
valueOf_1_2_3: getAccounts()
}
6.ES6中的箭头函数
ES5中,函数内部的this对象指向的是引用函数的对象。
比如:
var vm = this;
$('.btn').click(function(event){
vm.sendData()
})
但是在ES6中,箭头函数内部的this对象指的还是之前的作用域。
$('.btn').click((event) =>{
this.sendData()
})
注意下,ES6中箭头表达式有隐式的写法:
map(value => `hahahahah`)
如果箭头函数所在语句只有一行时,它会默认返回值。
如果是多行的,需要用return来显式表达返回的值。
7.ES6中的Promise
看看ES5中的一个延迟执行:
setTimeout(function(){
console.log("haha!")
}, 1000)
可以用ES6中的Promise重写
// 创建一个新的Promise实例,传递一个参数,这个参数是个函数
// 该函数接受两个参数,一个是resolve,代表成功回调,另一个是reject,指失败回调
var wait1000 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
}).then(() => {
console.log("haha!");
})
目前还没有看到有任何的好处,
看下一例子:
// 1秒后先显示'haha1',再过一秒显示'haha2'
setTimeout(function() {
console.log('haha1')
setTimeout(function() {
console.log('haha2')
},1000)
},1000)
可以用promise重写:
// wait1000是一个新的promise实例
// wait1000()表示1秒后将调用成功回调函数resolve
// 而这个成功回调函数resolve里又重新返回了个新的promise实例
// 新的promise实例wait1000()继续1秒后调用成功回调resolve
var wait1000 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000)
})
wait1000().then(function() {
console.log('haha1');
return wait1000();
}).then(function() {
console.log('haha2');
})
如果Promise实例在pending状态时,传给resolve()的是一个Promise对象,那么在then()里面,会等待这个Promise对象的完成,这么说会有点抽象,看下面的例子:
var promise4 = new Promise((resolve, reject) => {
var promise4_1 = new Promise((resolve, reject) => {
console.log("promise4_1 starts");
setTimeout(() => {
resolve("this is promise4_1 resolve");
}, 2000);
})
resolve(promise4_1);
}).then((msg) => {
console.log(msg);
console.log("haha");
})
// promise4_1 starts
// this is promise4_1 resolve
// haha
var promise4 = new Promise((resolve, reject) => {
var promise4_1 = new Promise((resolve, reject) => {
console.log("promise4_1 starts");
setTimeout(() => {
resolve("this is promise4_1 resolve");
}, 2000);
})
resolve(promise4_1);
}).then((msg) => {
console.log("haha");
console.log(msg);
})
// promise4_1 starts
// haha
// this is promise4_1 resolve
块级作用域的let和const
let类似于var,可以将变量作用域限制在当前块里。
我们开始用{}来定义块。
function calculateTotalAmount() {
let a = 0;
{
let a = 1;
return a; //a为1
}
return a; // a为0
}
const定义个不可变的变量。
9.ES6中的类
ES6的类会用prototype来实现而不是function。
现在有一个baseModel类,其中我们可以定义构造函数和getName()方法。
class baseModel{
constructor(options={},data=[]){
this.name=
this.url=
this.data=
this.options=
}
getName() {
}
}
10.ES6中的模块化
ES5中可以用script标签和IIFE(立即执行函数),或者其他的像AMD之类的库,但是在ES6中可以用export来暴露类。
ES5里:
//module.js
module.exports = {
port: 3000,
getAccounts: function() {
...
}
}
// main.js
var service = require('module.js')
但是在ES6中,我们可以用export和import
比如:
// module.js
export var port = 3000
export function getAccounts(url) {
...
}
// main.js
import {port, getAccounts} from 'module'
// 或
import * as service from 'module'
如何使用ES6(Babel)
并不是所有的浏览器都支持ES6,如果想要马上用ES6,需要准备个像Babel这样的编译器。
Babel对Gulp、Grunt和Webpack都有对应的插件。
比如对Gulp
npm install --save-dev gulp-babel
在gulpfile.js中,定义这么一个任务,将src目录下的app.js文件编译到build目录下:
// gulpfile.js
var gulp = require('gulp'),
babel = require('gulp-babel');
gulp.task('build', function(){
return gulp.src('src/app.js')
.pipe(babel())
.pipe(gulp.dest('build'))
})