JavaScript中显式数组属性与变量的区别

8

试图重构一个简单的函数:

// arr - array of objects with functions
function eventNotify(arr, event) {
    for (var i = 0; i < arr.length; i++) {
        var a = arr[i];
        if (typeof a[event] === 'function') {
            a[event]();
        }
    }
}

将它转化为这个样子:
function eventNotify(arr, event) {
    for (var i = 0; i < arr.length; i++) {
        var a = arr[i][event];
        if (typeof a === 'function') {
            a();
        }
    }
}

我无法理解为什么这样的更改会破坏我的所有测试。

第二种实现与第一种有何不同之处?

我甚至尝试分离索引的使用,以为可能会被视为三维数组:

var a = arr[i];
a = a[event];

但是,这没有任何区别。

请有人指出我在算法逻辑中到底改变了什么!现在我正在为此苦苦思索。


我正在Node.js 10.9下进行测试。


7
你正在打破对象关系,因此在调用函数时 this 不会被设置。 - Pointy
@Pointy,所以在显式数组寻址中,“this”可以工作,而不仅仅是一个变量。我知道秘密就在我头撞桌子的强度中...但这真是个大发现。如果你想把它变成一个答案,我会接受的 ;) - vitaly-t
在第一个示例中,函数上下文(this 值) 是 arr[i]。在第二个示例中,它是全局对象。 - ibrahim mahrir
1个回答

1

感谢@Pointy

我的错误在于没有看到语法a[event]()掩盖了这样一个事实,即它将this上下文设置为对象a,而简单的a()则不会,因此导致结果差异。


如果你只想执行 a(),你可以使用 bind。var a = arr[i][event].bind(arr[i]) - Keith
@Keith 我这样做是为了进行一些性能优化,通过替换一些 forEach 循环,在旧浏览器(如 IE9/10)中使用比 for 慢得多的方法。而你的解决方案将使它比那还要慢,因为你调用了一个创建并返回另一个函数以交换调用上下文的函数。 - vitaly-t
使用bind实际上可以提高性能,当然这取决于你如何使用它。但在循环内部使用bind并不理想。 - Keith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接