缘起
今天在写一个工具方法封装成对象模块导出时,由于成员方法内调用了其他成员方法,而且成员方法用了箭头函数
() =>
定义,导致使用this.成员方法()
不能调用该成员方法,console.log(this)发现为undefined
。
export default {
// 成员方法1
getVersion: () => {
return '1.0'
},
// 成员方法2
test: () => {
// 此处this为undefined,执行test方法会报错
this.getVersion()
},
// 成员方法3,常规函数写法,this指向正常
test2() {
this.getVersion()
},
// 成员方法4,常规函数写法,this指向正常
test3: function() {
this.getVersion()
},
}
缘由
在JavaScript
中,方法内的this
指向是动态的,它取决于函数的调用方式。在对象内的方法被调用时,this通常指向调用该方法的对象。但是,如果方法被其他方式调用(例如,作为回调函数或使用apply/call
改变this
的绑定),this可能会指向其他对象。
如果在对象内的方法中this
不指向该对象,常见的原因是因为使用了不正确的调用方式,例如使用了箭头函数或者方法被提升到了全局作用域。
解决方法:
确保方法是作为对象的属性直接调用的,而不是作为一个全局函数或者在其他上下文中调用。
如果使用箭头函数,箭头函数不绑定自己的this
,它会捕获其在定义时所处的上下文中的this
值。如果需要在对象内部方法中使用this
,请使用常规函数声明。
使用.bind()
来在对象方法被提取时保持this
的引用。
如果是作为回调函数调用的,请确保回调内的this
是正确绑定的,可以使用.call
或.apply
来指定this
的值。
示例代码:
// 假设有以下对象
const myObject = {
name: 'example',
// 使用常规函数,确保this指向myObject
sayName: function() {
console.log(this.name);
},
// 如果需要在方法中使用箭头函数,请确保this的行为
sayNameWithArrow: () => {
console.log(this.name); // 这里的this可能不指向myObject
}
};
// 正确调用方式
myObject.sayName(); // 输出 'example'
// 如果使用箭头函数需要修正为:
const myObject = {
name: 'example',
sayNameWithArrow: () => {
console.log(this.name); // 如果在对象定义以外的地方访问,这里的this可能不是预期的对象
}
};
// 使用常规函数或者bind来解决
myObject.sayNameWithArrow = function() {
console.log(this.name); // 这里的this指向myObject
};
// 或者
myObject.sayNameWithArrow = () => {
console.log(this.name); // 如果需要访问外层的this,可以在外层作用域中绑定this
};
// 使用bind来确保this指向myObject
myObject.sayNameWithBind = function() {
console.log(this.name); // 这里的this指向myObject
}.bind(myObject);