背景
在 ES6 中,引入了 Arrow Function,它的语法短小精悍,书写简便,成为了前端开发人员的新宠。但是,由于 Arrow Function 的 this 指向固定为定义时的作用域,与普通函数的 this 指向不同,会带来一些问题。
在不同的场景下,this 的指向也不同,对于前端开发人员来说,这个问题很重要,因为它涉及到了前端开发中非常常见的回调函数、事件绑定等问题。本文将详细阐述 ES6、ES7 的 Arrow Function 在不同场景下的 this 指向问题,并提供解决方案。
问题
在 Arrow Function 中,this 的指向不同于普通函数。在普通函数中,this 的指向由函数调用时的上下文决定,而在 Arrow Function 中,this 的指向由定义时的上下文决定。
例如:
// javascriptcn.com 代码示例 const obj = { name: '张三', sayName: function() { console.log(this.name); } }; obj.sayName(); // 输出 '张三' const getName = obj.sayName; getName(); // 输出 undefined
在上面的代码中,obj.sayName 是一个普通函数,它的 this 指向 obj,因此输出了 '张三'。而 getName 是一个引用了 obj.sayName 的函数,它的 this 指向在调用时并未指定,因此输出 undefined。
在 ES6 中,引入了 Arrow Function,它的 this 指向固定为定义时的上下文。例如:
// javascriptcn.com 代码示例 const obj = { name: '张三', sayName: function() { const getName = () => { console.log(this.name); }; getName(); } }; obj.sayName(); // 输出 '张三'
在上面的代码中,getName 是一个 Arrow Function,它的 this 指向与 sayName 的 this 指向相同,都指向 obj,因此输出了 '张三'。
然而,在某些场景下,Arrow Function 的 this 指向可能会带来一些问题。
解决方案
使用 bind 方法
可以使用 Function.prototype.bind() 方法来改变 Arrow Function 的 this 指向。bind 方法会创建一个新的函数,其 this 值会被绑定到传递给 bind() 方法的值。
例如:
// javascriptcn.com 代码示例 const obj = { name: '张三', sayName: function() { const getName = () => { console.log(this.name); }; getName.bind(this)(); } }; obj.sayName(); // 输出 '张三'
在上面的代码中,我们使用 bind() 方法将 getName 函数的 this 值绑定到 obj 上,使得其 this 指向与 sayName 相同,从而输出了 '张三'。
使用箭头函数
在某些场景下,可以使用箭头函数来替代普通函数,从而避免 this 指向的问题。由于箭头函数的 this 值与定义时的上下文相同,因此可以避免 this 指向的混乱。
例如:
// javascriptcn.com 代码示例 const obj = { name: '张三', sayName: function() { const getName = () => { console.log(this.name); }; const handleClick = () => { console.log(this.name + '被点击了'); }; document.querySelector('button').addEventListener('click', handleClick); } }; obj.sayName();
在上面的代码中,我们使用箭头函数 handleClick 来替代普通函数,从而避免了 this 指向的问题。
使用类的成员方法
在 ES6 中,我们可以使用类来创建对象。类的成员方法中的 this 指向固定为实例对象,因此可以避免 this 指向的混乱。
例如:
// javascriptcn.com 代码示例 class Person { constructor(name) { this.name = name; } sayName() { console.log(this.name); } handleClick = () => { console.log(this.name + '被点击了'); } } const p = new Person('张三'); p.sayName(); // 输出 '张三' document.querySelector('button').addEventListener('click', p.handleClick);
在上面的代码中,我们使用类的成员方法 handleClick 来替代普通函数,从而避免了 this 指向的问题。
总结
ES6、ES7 的 Arrow Function 在不同场景下的 this 指向问题,可能会带来一些混乱。我们可以使用 bind() 方法、箭头函数、类的成员方法等方式来解决这个问题。在实际开发中,我们需要根据具体的场景,选择合适的解决方案。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6556dc5dd2f5e1655d13c164