js中 一个保存了很多对象的数组1 一个数组2 循环把1里面的对象的一个函数添加到数组2 再通过数组2调用那个函数,为什么说那个函数的对象未定义呢?
代码大概是
定义对象O O有里面有个函数fun()
var a=[new O(),new O(),...];
var b=[];
循环i =0;...;i++ b.push(a[i].fun)
再调用 var f=b[0]; f(); 出错。。
本问题来自阿里云开发者社区的【11大垂直技术领域开发者社群】。 https://developer.aliyun.com/article/706511 点击链接欢迎加入感兴趣的技术领域群。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在JavaScript中,当你将对象的方法(如O.prototype.fun
)直接从一个对象提取到数组,并试图通过这个数组来调用它时,实际上你会丢失该方法原本的上下文(也就是this
指向)。当函数内部访问this
时,它会引用错误的对象,或者在严格模式下(use strict
),this
可能为undefined
。
解决这个问题的一种常见做法是使用箭头函数或者.bind()
方法来固定函数的上下文。但在这个场景下,更简单的做法是不直接存储函数本身,而是存储一个能够正确调用该函数的包装器(wrapper)。
下面是修改后的代码示例:
// 假设 O 是一个具有 fun 方法的对象构造函数
function O() {
this.fun = function() {
console.log(this);
};
}
var a = [new O(), new O()]; // 保存了很多对象的数组
var b = []; // 准备存放调用函数的包装器
// 循环将每个对象的 fun 方法以包装器形式添加到数组b中
for (let i = 0; i < a.length; i++) {
b.push((index) => a[index].fun()); // 使用闭包保留索引
}
// 调用 var f=b[0]; f(); 的方式会出错,改为:
b0; // 正确调用第一个对象的fun方法
这里,我们没有直接将a[i].fun
推入数组b
,而是创建了一个匿名函数,该函数接受一个索引作为参数,并使用这个索引来调用原对象上的方法。这样就确保了函数被调用时,其内部的this
仍然指向正确的对象实例。
如果你确实需要直接通过数组调用函数且保持正确的上下文,考虑使用.bind()
方法绑定每个函数的上下文,但这会增加额外的内存开销,因为.bind()
会创建一个新的函数实例:
for (let i = 0; i < a.length; i++) {
b.push(a[i].fun.bind(a[i])); // 使用bind绑定上下文
}
这样,你就可以直接通过b[0]();
来调用第一个对象的fun
方法,而不会遇到未定义的错误。