开发者社区 问答 正文

循环把1里面的对象的一个函数添加到数组2,再通过数组2调用那个函数,为什么说那个函数的对象未定义呢

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 点击链接欢迎加入感兴趣的技术领域群。

展开
收起
游客mxpnxp6g3cq7o 2019-08-26 10:59:54 603 分享 版权
阿里云 AI 助理回答

在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方法,而不会遇到未定义的错误。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答地址: