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

73 篇文章 23 订阅

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;//true

const 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下通过测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值