javascript - 使用 IIFE 包装 JavaScript 函数 getter

标签 javascript

我正在查看 JavaScript 代码,我注意到跨多个函数的以下模式

function getValues() {
    var values = ['a', 'b', 'c'];
    return (getValues = function () {
        return values;
    })();
}

据我所知,以下函数具有相同的效果

function getValues() {
    return ['a', 'b', 'c'];
}

这里用IIFE包起来有什么特别的效果吗?特别是以下部分 return (fnName = function() {...})() 请注意,变量总是分配有与函数相同的名称。

注意:我非常熟悉 IIFE 的概念和它的用处,不要与下面的模式混淆

var fn = (function() {
    function fn() {
    }
    fn.prototype.function1 = function () { /* ... */ }
    return fn;
})();

在我的问题中,变量是在函数内部分配的,而不是相反。

最佳答案

好吧,在这种情况下,它是一种奇怪的内存技术的一部分。

要注意的关键点是函数重新分配自身:

return (getValues = function () {
        ^^^^^^^^^^^^

所以,当第一次调用 getValues 时,getValues 创建了一个以 values 作为闭包的新函数,然后它用那个新函数替换自己。

因此,对 getValues 的进一步调用将调用相同的内部函数,该函数从闭包中返回值,而无需每次都创建不同的对象。

您可以通过检查返回值来检查此行为:

console.log(getValues() === getValues()); //true

虽然在您的实现中,这是行不通的:

function getValues() {
    return ['a', 'b', 'c'];
}

console.log(getValues() === getValues()); //false

重新分配函数意味着 getValues 本身的值将在第一次和第二次调用之间发生变化。 所以:

var gv0 = getValues;
getValues();
console.log(gv0 === getValues); // false

如果为该函数创建多个引用,则该行为有自身的风险:

var gv0 = getValues;
console.log(getValues() === gv0()); // false!

顺便说一句,编写记忆化的通常(且更易读)的方法是将外部函数设为 IIFE,它返回内部函数。它还消除了重新分配的需要。

var getValues = (function () {
    var values = ['a', 'b', 'c'];
    return function () {
        return values;
    };
})();

然而,这将立即创建对象,而有问题的代码只会在第一次调用时创建它。

如果对象的创建开销很大,这种差异就很重要。

关于javascript - 使用 IIFE 包装 JavaScript 函数 getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70493601/

相关文章:

javascript - 使用 JavaScript/jQuery 将 HTML 实体分配为属性值

javascript - 禁用正文中的滚动 - ExtJS

javascript - mouseover mouseout JQuery 时自动播放/暂停

javascript - TypeScript 与 ES6 (ECMAScript 2015) 的兼容性如何(将如何)

javascript - mvc5 的日期时间的 DataFormatString

javascript - Jade 中数组的长度未定义

javascript - 在存储在变量中的组件中传递 Prop

javascript - 如何获取 slider wordpress 中的幻灯片数量/实际数量

javascript - JS 破坏我的 Random 函数

javascript - AJAX与WCF获取跨域导致parseError