我正在查看 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/