一直以来,我对ES6都不甚感兴趣,一是由于在生产环境中使用ES5已经是到处碰壁,其次则是只当这ES6是语法糖未曾重视。
只是最近学习react生态,用起babel来转换jsx之余,也难免碰到诸多用上ES6的教程、案例,所以便稍做学习。这一学习,便以为这语法糖实在是甜,忍不住尝鲜,因而记录部分自觉对本身有用的方法在此。javascript
箭头函数是一个典型的语法糖,即创造了一种新语法来简化javascript中函数的写法:java
// ES5 var selected = allJobs.filter(function (job) { return job.isSelected(); }); // ES6 var selected = allJobs.filter(job => job.isSelected());
上面这是函数只有一个形参的状况,下面列举函数有多个形参的状况:react
// ES5 var total = values.reduce(function (a, b) { return a + b; }, 0); // ES6 var total = values.reduce((a, b) => a + b, 0);
语法大致是这样:([函数的形参,多个参数则以逗号分隔]) => [函数返回的值/表达式]
另外,箭头函数也可使用{}
来引入函数块语句,不过这样的话其实就只是简写了function
这一个单词了,意义不是很大,下面放个例子:编程
// ES5 $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); }); // ES6 $("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon(); });
对我来讲,简写并不吸引我,吸引个人,是箭头函数的一个重要特性:箭头函数没有它本身的this值,箭头函数内的this值继承自外围做用域。数组
2016-05-31修改: @n͛i͛g͛h͛t͛i͛r͛e͛
同窗指出babel
arrow function 不是“没有本身的 this”,而是绑定了定义时的 context;这一特性等价于之前的
Function.prototype.bind
我翻查了一下MDN,里面是这么写的:闭包
箭头函数则会捕获其所在上下文的 this 值,做为本身的 this 值。
所以,@n͛i͛g͛h͛t͛i͛r͛e͛
同窗的说法是有理的。函数式编程
这在编写回调函数的时候就很是好用了,咱们不再须要利用闭包来保存this了(尤为是,很容易忘记保存this而直接在回调函数里用了this):函数
{ add: function(piece) {}, ... addAll: function addAll(pieces) { var self = this; _.each(pieces, function (piece) { self.add(piece); }); }, ... } // ES6 { add: function(piece) {}, ... addAll: function addAll(pieces) { _.each(pieces, piece => this.add(piece)); }, ... }
自ES6中let
的出现,javascript终于迎来了块级做用域({}、for、if)。学习
2016-05-31修改:
此处表达有误,应为:自ES6,javascript开始拥有块级做用域,而let
则是配合块级做用域,做为替代var
的一个语法定义。
有了块级做用域,不再用担忧临时变量污染到外层的变量了:
function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 }
const
是用来定义常量的,一旦定义了就不可修改(一修改就报错)。用途嘛,也比较单一,就是定义一下配置项什么的,省得被团队里的愣头青写的代码给瞎改了。
2016-05-31修改 @n͛i͛g͛h͛t͛i͛r͛e͛
同窗提出一个“命名绑定”的概念,并举出一个相应的例子:
const config = {}; config.env = 'development'; // 这不会报错 config = {}; // 这才会报错
请恕我才疏学浅,尚不能理解“命名绑定”呀、函数式编程之类的。我对上面这个例子的理解是,config只是一个object的引用,不管这个object自己怎么变化,只要config这个变量的“指向”没变化,那就不会报错。
destructuring是解构的意思,ES6容许按照必定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。来两个例子看看你们就明白了。
'use strict'; // 数组的解构赋值 let [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); // 1 console.log(bar); // 2 console.log(baz); // 3 // 对象的解构赋值 var { foo, bar } = { foo: "aaa", bar: "bbb" }; console.log(foo); // "aaa" console.log(bar ); // "bbb" // 字符串的解构赋值 const [a, b, c, d, e] = 'hello'; console.log(a + b + c + e); // 'hello'
跟箭头函数同样,也是个语法糖,那这是用在什么地方呢?请不要着急,听我细细道来:
在咱们封装函数的时候,若是形参较多,为了使用者不须要按顺序来传入参数,每每用一个object来承载全部的参数,例如这样:
// 二逼青年写法 function study(id, name, sex, grade, nickname, age, address) { console.log(id); console.log(name); console.log(sex); console.log(grade); console.log(nickname); console.log(age); console.log(address); } // 正常青年写法 function study(params) { console.log(params.id); console.log(params.name); console.log(params.sex); console.log(params.grade); console.log(params.nickname); console.log(params.age); console.log(params.address); }
这种作法,虽然说使用者是方便了,但写函数的人却麻烦了,每次用参数都要带上params.
,或者再写个var id = params.id
来让后续的使用方便一些。
然而,有了destructuring
后,咱们有了更方便的写法:
function study({id, name, sex, grade, nickname, age, address}) { console.log(id); console.log(name); console.log(sex); console.log(grade); console.log(nickname); console.log(age); console.log(address); } study({ id: 1, name: '林有德', sex: '男', grade: '一年级', nickname: '布莱德', age: 12, address: '木马号' });
这样一来,使用者用起来很方便,而函数内部又直接解构赋值到各变量上,用起来也方便多了。