对象的闭包

3

我对这段代码中闭包的工作原理感到有些困惑:

function Spy(target, method) {
    var result = {count: 0},
        oldFn = target[method];
    target[method] = function(input) {
        result.count++;
        return oldFn.apply(target, arguments);
    }
    return result;
}

因此,当您将其分配给变量时,例如

var logSpy = Spy(console, 'log')

logSpy是一个带有计数属性的对象。如果您调用console.log,重写的函数将增加result.count值,但它所访问的结果是封闭的,对吗?那么封闭对象和全局logSpy对象之间如何建立联系呢?我猜logSpy对象是引用封闭对象,因为对象通过引用传递给变量?那么作为对象的logSpy在全局执行上下文中技术上不存在,而只是对闭包的引用?


我认为这是正确的 - 在闭包内定义函数可以使该函数访问该闭包中的所有变量。然而,我只能从经验上说,我不知道JS的内部工作原理。 - sg.cc
在JavaScript中,函数对象本身包含一个指向其声明作用域中变量的对象的不可访问属性。链接 - xersiee
1个回答

2
当您调用Spy(console, 'log')时,它会执行以下四个操作:
  1. 创建一个result对象。
  2. oldFn设置为(对)console.log的引用(或者更确切地说是console['log'])。
  3. console['log']设置为一个新函数,该函数“关闭”resultoldFn
  4. 返回(对)result的引用。
因此,发生的情况是console.log现在是一个函数,但是resultoldFn仍然存在于内存中——它们尚未被垃圾回收,因为在该新函数中有对它们的引用。
当您调用console.log时,它会更新result对象的count属性(您可以使用logSpy引用它),然后使用正确的上下文/参数调用“备份”的oldFn函数。

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