ES6学习——新的语法:Arrow Functions

来源:互联网 发布:合肥美工招聘 编辑:程序博客网 时间:2024/05/17 07:56

Arrow Functions并不是什么新鲜玩意了,在Java 8和Apple Swift语言中也都有这种写法,只不过有的语言用单箭头(->),JS中用双箭头(=>),大同小异,单箭头更像C或者C++中的指针语法。ES6中描述Arrow Functions的章节在14.2,有兴趣的可以自己去看。


下面先看个简单的例子,然后在介绍其他特征:

let arr = [1, 2, 3];let squares = arr.map(x => x * x);console.log(squares);[1,4,9]

几种写法:

() => { } // 无参数x => { } // 一个参数(x, y) => {} // 多个参数x => { return x * x } // 函数体x => x * x // 如果函数体只有一条语句,并且是返回语句,可以简写,等同于上面的大括号写法//如果函数体只有一条,并且是表达式,则可以省略大括号let consoleFunc = x => console.log(x);//如果函数体内是声明语句,则不能省略大括号let throwFunc = x => {throw x };//如果去掉大括号,SyntaxError: expected expression, got keyword 'throw'

优先级:

箭头函数的优先级是很低的,仅比=号高一点:

console.log(typeof () => {}); //SyntaxError: invalid arrow-function arguments (parentheses around the arrow-function may help)console.log(typeof (() => {})); //'function'(() => {}) instanceof Function;//trueconst value = () => foo();/*等同于*/const value = () => (foo())//但是不等同于const value = (() => foo)()//如果函数体只有一条语句,并且返回的是个对象字面量,应该怎么写?let f1 = x => { bar: 123 }//还是let f2 = x => ({ bar: 123 })//答案是下面这种,但上面的写法同样不会报错!这里需要特殊注意,上面那种写法会被解析成复合语句,复合语句里面是个标签语句,然后跟着一个数值表达式。//所以执行f1不会有什么结果,即返回undefined;执行f2则返回对象字面量

用箭头函数重写IIFE:

(function () {     console.log("IIFE");}());(() => {    console.log("Immediately Invoked Arrow Function");})();

箭头函数参数解构语法:

[[1,2], [3,4]].map(([a,b]) => a + b);//[3,7][{x:3,y:4}, {x:5,y:6}].map(({x:XX,y}) => XX + y)//[7,11]

箭头函数参数默认值语法:

[1, undefined, 3].map((x='yes') => x);//[1, "yes",3]//默认值+解构[{x:3,y:4}, {x:5},{y:8}].map(({x:XX=0,y:y=0}) => XX + y);//[7,5,8][[1,2], [3,4],[5]].map(([a,b=0]) => a + b);//[3,7,5]

箭头函数体中的this:

在ES6中有两种this,一种是原有的动态绑定的this,另一种叫lexical this,就是这个this在词法解析的时候就确定了。而箭头函数属于后一种,ES6规范14.2的最后有这样一段NOTE:

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function.

怎么理解上面这段话,看个简单的例子,你也许就明白了:

function Prefixer(prefix) {    this.prefix = prefix;}Prefixer.prototype.prefixArray = function (arr) {    return arr.map(function (x) {        return this.prefix + x;    });};//上面这段代码是不work的,因为在map的回调中this是动态绑定的,在非strict模式下,this是window。在严格模式下,将报错。//下面用箭头函数解决问题function Prefixer(prefix) {    this.prefix = prefix;}Prefixer.prototype.prefixArray = function (arr) {    return arr.map((x) => {        return this.prefix + x;    });};//箭头函数的this不是动态绑定的,是在词法分析阶段就确定了,map中的this就是prefixArray方法体this,即Prefixer实例

在看个用箭头函数解决事件绑定中的this:

var controller = {prefix:"123",makeRequest: function() {document.getElementById("btn").addEventListener( "click", () => {console.log(this.prefix);}, false );}};window.onload = function(){controller.makeRequest();}

箭头函数简化了函数的语法,并且解决了回调函数中的this问题,以后这种写法肯定会大范围普及,所以应该重点掌握。


*以上全部代码在Firefox 43下通过测试

0 0