如何为多个对象字面量绑定通用方法并正确指向this?
解决对象方法中this指向错误的问题
嘿,这个问题我之前也碰到过!核心原因是箭头函数的this绑定规则和普通函数不一样——箭头函数没有自己独立的this,它的this是从定义时的外层作用域继承来的,而不是调用它的那个对象。所以你直接把箭头函数f赋值给obj1.f后,调用obj1.f()时,this根本指向不到obj1,自然拿不到this.list啦。
下面给你几种可行的解决办法,按需选择:
1. 改用普通函数定义通用方法
这是最直接的方案,普通函数作为对象方法调用时,this会自动指向调用它的对象:
// 把箭头函数换成普通函数 const f = function() { console.log(this.list); }; let obj1 = { list: [], a() {}, b() {} }; let obj2 = { list: [], c() {}, d() {} }; obj1.f = f; obj2.f = f; obj1.f(); // 输出 [] obj2.f(); // 输出 []
2. 用bind强制绑定this到目标对象
如果一定要保留箭头函数(虽然这里其实没必要),可以通过bind方法把this固定到每个对象上:
const f = () => console.log(this.list); let obj1 = { list: [], a() {}, b() {} }; let obj2 = { list: [], c() {}, d() {} }; // 绑定this到对应的对象 obj1.f = f.bind(obj1); obj2.f = f.bind(obj2); obj1.f(); // 输出 [] obj2.f(); // 输出 []
不过这种方式有个小缺点:绑定后的this是固定死的,后续如果把obj1.f赋值给其他变量调用,this还是指向obj1,灵活性不如普通函数。
3. 用原型/继承实现方法共享(更优雅的批量方案)
如果有多个这类对象需要添加相同方法,用原型继承或者ES6类会更优雅,避免重复给每个对象赋值:
方式一:使用Object.create实现原型继承
// 定义包含通用方法的基础对象 const baseObject = { f() { console.log(this.list); } }; // 创建obj1和obj2,自动继承baseObject的方法 let obj1 = Object.create(baseObject); obj1.list = []; obj1.a = function() {}; obj1.b = function() {}; let obj2 = Object.create(baseObject); obj2.list = []; obj2.c = function() {}; obj2.d = function() {}; obj1.f(); // 输出 [] obj2.f(); // 输出 []
方式二:使用ES6类
class BaseObj { constructor() { // 初始化每个实例的list属性 this.list = []; } // 通用方法f f() { console.log(this.list); } } // 创建实例,自动拥有f方法 let obj1 = new BaseObj(); obj1.a = function() {}; obj1.b = function() {}; let obj2 = new BaseObj(); obj2.c = function() {}; obj2.d = function() {}; obj1.f(); // 输出 [] obj2.f(); // 输出 []
这种方式更符合现代JavaScript的面向对象编程习惯,所有实例共享f方法,不用逐个手动添加,维护起来也更方便。
内容的提问来源于stack exchange,提问作者user12187913
相关产品推荐
相关产品推荐

