单个参数,且函数执行体仅包含一条语句,返回值无需return关键字。
const foo = a => a + 1; foo(1); // 2 |
单个参数,函数执行体含多条执行语句,需要使用块级代码段,即使用{}括起来,不过此时若存在返回值,务必记得return。
const foo = a => { a *= 2; return a + 1; } foo(1); // 3 |
多个参数需要()括起来。
const test = (a, b) => a + b; test(2, 3); // 5 |
多个参数,且函数中包含多条执行语句。
const foo = (a, b) => { a *= b; return a + 1; } foo(2, 3); // 7 |
从以上代码展示看,仅仅是语法糖在代码编写上的改进,其核心价值尚未体现。在ES5中,经过遇到上下文(context)混乱问题,看一下典型案例的分析。
var obj = { a: function() { setTimeout(function() { this.b(); }, 0); }, b: function() { alert('run b'); } }; obj.a(); // Uncaught TypeError: this.b is not a function |
报错原因:理解JS中this指向有个简单的原则,即方法被哪个对象调用,方法内部的this就指向哪个对象。在上例中,setTimeout声明的执行体被window对用调用,而在window对象下没有方法b的声明,因而报错。
要验证这个结论是否正确也很简单,在window作用域下声明方法b,观察执行结果即可。
window.b = function() { alert('window scope'); }; var obj = { a: function() { setTimeout(function() { this.b(); }, 0); }, b: function() { alert('run b'); } }; obj.a(); // window scope // Uncaught TypeError: this.b is not a function |
每遇到这种情况,实现代码设计者意图,通常有两种解决方式:
· 在setTimeout执行体内使用当前对象的引用,不要直接用this关键字
· 利用call、apply动态改变this指向
第二种方式在此场景中并不必要,下面再细说,这里使用第一种方式即可达成目标。
var obj = { a: function() { var self = this; setTimeout(function() { self.b(); }, 0); } }; |
在ES6中,可使用箭头函数取代以上二种方案。
let obj = { a () { setTimeout( () => this.b(), 0); }, b() { alert('run b'); } }; obj.a(); // run b |
call、apply均可动态改变函数内this指向,区别是传参方式不同。
var b = 'window作用域变量'; var obj = { a: function(p1, p2) { console.log(p1, p2) console.log(this.b); }, b: 'obj对象属性' }; obj.a(1, 2); // 1 2 =====> obj对象属性 obj.a.call(window, 1, 2); // 1 2 =====> window作用域变量 obj.a.apply(window, [1, 2]) // 1 2 =====> window作用域变量
|
//ES5 function test(a) { if (typeof a == 'undefined') { a = 1; } console.log(a); } test(); // 1 |
在ES6中有了更优雅的做法:
const test = (a = 1) => { console.log(a); } test(); // 1 test(2); // 2
// 对于对象类型的参数 const foo = ({a = 1, b = 2} = {}) => { console.log() } |
而对于复杂参数类型,比如参数值为对象,在保证参数默认值方面,ES6会让你写代码的速度飞起来,并且让代码看起来不那么脏,请比较以下代码。
// ES5 function test(cfg) { cfg = cfg || {}; cfg.str = cfg.str || 'aaaa'; cfg.callback = cfg.callback || function() {}; // todo... }
// ES6 const test = ({str = 'aaaa', callback = ()=>{}} = {}) => { // todo... }; |