JS中箭头函数与this的写法和理解是一个非常重要的问题,因为箭头函数的this规则和普通函数有所不同,如果不理解它的具体规则,就容易出现一些令人困惑的问题。下面就是一份关于箭头函数和this的完整攻略。
箭头函数的基本语法
箭头函数是在ES6中引入的一种语法,它是一种特殊的函数,它有以下的形式:
(parameter1, parameter2, ..., parameterN) => { statements }
箭头函数的语法比较简单,它只有一个表达式,并且这个表达式会自动作为函数的返回值。当函数体只有一个表达式的时候,可以省略花括号 {}
和return关键字。
(parameter1, parameter2, ..., parameterN) => expression;
当前只有一个参数的情况下,可以省略掉括号。
parameter => expression;
如果箭头函数没有参数,需要使用一对空的括号。
() => { statements }
this的基本概念
在JavaScript的函数中,this是一个非常关键的概念,它通常用来引用当前的执行上下文。在箭头函数中,this的值也是非常重要的,因为它的值不像普通的函数那样,由函数被调用的方式来决定,而是由定义时的上下文来决定。
在JS中,this可以指向以下几个对象:
- 全局对象
- 当前对象
- 新创建的对象
- 显式指定的对象
在普通函数中,this的值是根据函数的调用方式来确定的。举个例子,下面这个函数将会输出全局对象:
function foo() {
console.log(this);
}
foo();
而在箭头函数中,this的值是在函数定义时确定,而不是在函数被调用时确定,因为箭头函数没有自己的this,它会继承它的父级上下文的this。
箭头函数中的this
在箭头函数中,this的值是在函数定义时确定的,而不是在函数被调用时确定的。下面是一个例子,可以说明箭头函数中的this:
let person = {
name: 'Tom',
sayName: () => {
console.log(this.name);
}
}
person.sayName();
上面的代码将会输出 undefined
。因为sayName函数的this是在定义时就被确定了,并且它指向了全局对象window,而非person对象。
因此箭头函数是不能被作为构造函数使用的,因为它不会创建一个新的对象。
箭头函数不能使用call、apply、bind方法,因为这些方法在ES5中被用于改变函数执行时期的this值。
箭头函数与普通函数的区别
除了this的不同,箭头函数还有以下与普通函数不同:
- 没有自己的this对象
- 不能用作构造函数,不能使用new命令
- 没有原型
- 不可以改变this指向,即不能使用call()、apply()、bind()这些方法
那么下面的示例案例,就可以更好的理解普通函数与箭头函数的不同:
// 定义一个对象
let person = {
age: 25,
// 普通函数
sayAge: function() {
console.log(this.age);
},
// 箭头函数
sayAgeArrow: () => {
console.log(this.age);
}
};
// 调用普通函数
person.sayAge(); // 输出25
// 调用箭头函数
person.sayAgeArrow(); // 输出undefined
上面的代码中,普通函数 sayAge
内的 this
指向了当前的对象 person
,而箭头函数 sayAgeArrow
的 this
指向了全局对象。因此,当 sayAgeArrow
函数被调用时,它输出的是 undefined
。
注意事项
虽然使用箭头函数可以减少一些代码量,但是在实际的开发中,还是需要注意以下几点:
- 箭头函数不能作为构造函数,可以使用普通函数来作为构造函数。
- 箭头函数不能被当作方法使用,因为它没有自己的this对象,this指向了上层作用域。
- 箭头函数中的arguments关键字会继承上层作用域中的arguments。
- 箭头函数不能使用ES5的call、apply和bind方法给this指向赋值,但可以使用展开操作符或者数组的解构来传递参数。
示例说明
下面是两个示例,用于说明箭头函数和this的规则:
示例一:简单的箭头函数
let person = {
name: 'Tom',
sayName: () => {
console.log(this.name);
}
}
person.sayName();
上面的代码将会输出 undefined
,因为箭头函数中的this指向了全局对象,而非person对象。
示例二:箭头函数作为事件处理程序
<button id="myButton">点击我</button>
let myButton = document.getElementById('myButton');
myButton.addEventListener('click', () => {
console.log(this); // 输出 Window 对象
});
上面的代码中,箭头函数用作事件处理程序。在事件处理程序中,箭头函数的this值指向了全局对象window,而不是事件的目标元素myButton。