命名式函数、函数表达式、箭头函数
// 命名式函数
function normalFn(参数) {
// 方法体
return 'normalFn';
}
// 函数表达式
const normalFn = function(参数) {
// 方法体
return 'normalFn';
}
// 箭头函数
const arrowFn = (参数) => {
// 方法体
return 'arrowFn';
}
箭头函数是在ES2015(ES6)标准中新增的,语法和之前的两种方式不同
区别:
-
this指向
-
普通函数中this的指向是动态的,其值取决于函数是如何被调用的,有以下4种
1、在直接调用时,this指向为全局对象(严格模式下为undefined)
function fnc() { console.log(this); } fnc(); // 全局对象(global 或 window) // 打印出的是window对象
2、方法调用时,this指向调用该方法的对象
let obj = { fnc1(){ console.log('fnc1', this === obj); } } obj.fnc2 = function() { console.log('fnc2', this === obj); } function fnc3() { console.log('fnc3', this === obj); } obj.fnc3 = fnc3; obj.fnc1(); // true obj.fnc2(); // true obj.fnc3(); // true
3、new调用时,this指向新创建的实例对象
function fnc() { console.log(this); } let obj = new fnc(); // fnc 的实例 fnc {} 这里就是obj // 打印的是 fnc {}
4、call、apply、bind调用时,this指向三种方法的第一个参数
function fnc() { console.log(this); } let obj = { name: '张三', age: 18 } fnc.call(obj) // obj对象 fnc.apply(obj) // obj对象 fnc.bind(obj)() // obj对象 // 注意:bind() 函数是创建一个新的函数,不会立即执行,需要手动调用
5、箭头函数中的this指向是静态的,始终指向创建时所在作用域指向的对象
const obj = { fnc(arr) { console.log(this === obj); // true(obj) const cb = () => { console.log(this === obj); // true(obj) }; arr.forEach(cb); } }; obj.fnc([1, 2, 3]);
注:因为箭头函数没有自己的this指针,通过call、apply方法调用一个函数时,知恩能够传递翻出,第一个参数会被忽略
var adder = { base : 1, add : function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // 输出 2 console.log(adder.addThruCall(1)); // 仍然输出 2
-
-
构造函数
-
箭头函数不能用作构造器,和new’一块使用会抛出错误
var Foo = () => {}; var foo = new Foo(); // 结果是报错
-
箭头函数没有prototype属性
var Foo = () => {}; console.log(Foo.prototype); // 打印undefined
-
-
参数
在参数的区别主要在于,箭头函数不能绑定arguments对象
const fn = () => arguments[0]; fn(1,2,3,4); // 报错 可以考虑用es6中的 const fn = (...args) => args[0]; fn(1,2,3,4); // 打印结果是1
-
返回值,箭头函数常规写法,必须有返回值
var fn = x => x * x; // 简写函数 省略 return var fn = (x, y) => { return x + y }; //常规编写 必须有明确的返回值
总结:
1:箭头函数没有自己的this,并且是静态的,它的this始终指向创建时所在作用域指向的对象
2:箭头函数不能new构造实例,没有prototype属性
3:箭头函数不绑定arguments,可以用ES6中的rest参数代替
4:箭头函数不能使用call、apply、bind方法改变this指向