在阅读问题的答案后:JavaScript inner-functions and Performance
我想知道在这种情况下是否可以以某种方式缓存内部函数(doSomethingCool):
function newUser(user){
function doSomethingCool(){
console.log(user);
}
}
答案 0 :(得分:4)
你无法真正缓存闭包。如果这样做,那么它仍然会关闭它首次定义的函数的变量。
例如,您可以考虑这样做,乍一看可能看起来不错:
var newUser = (function() {
var doSomethingCool;
function newUser(user){
doSomethingCool = doSomethingCool || function(){console.log(user);};
doSomethingCool();
}
return newUser;
}());
我们第一次调用newUser
时,将创建doSomethingCool
函数。这是输出:
> newUser('foo')
foo
当我们第二次调用该函数时,将重用该闭包。这是输出:
> newUser('bar')
foo
为什么呢?因为闭包只关闭函数调用的变量,所以它是在。
中定义的如果你真的想要“缓存”这个功能,你必须对它进行参数化:
var newUser = (function() {
var doSomethingCool;
function newUser(user){
doSomethingCool = doSomethingCool || function(user){console.log(user);};
doSomethingCool(user);
}
return newUser;
}());
但我不会称之为封闭。从技术上讲,是一个闭包,但你没有使用这个属性。
实际上,这样写起来要容易得多:
var newUser = (function() {
var doSomethingCool = function(user){...};
function newUser(user){
doSomethingCool(user);
}
return newUser;
}());
答案 1 :(得分:1)
使用闭包的目的是保留创建它的上下文。如果你“缓存”你的闭包,对user
的引用将始终是相同的,从而失去了目的。你可能想要的是:
function User(name) {
this.name = name;
}
User.prototype.doSomethingCool = function() {
console.log(this.name);
}
var userA = new User('a');
var userB = new User('b');
userA.doSomethingCool();
userB.doSomethingCool();
使用该代码,在User的原型上只创建了一个doSomethingCool
函数,但它的行为会根据它的调用方式而改变。
如果您只是想创建一个仅在newUser
内使用但没有利用闭包属性的实用程序函数,那么移动函数并接受用户可能会更好论点。也就是说,我非常怀疑它会以任何明显的方式影响你的表现。
答案 2 :(得分:0)
这是一个使用基本闭包和函数的简单缓存。它的驱逐策略是一种基于概率的策略,但是您可以轻松地将其修改为基于时间的策略。与其他解决方案不同,该解决方案不需要您调用new并委托传入的函数。它还使用一个对象作为缓存
const cache = (f, prob) =>{
const c = {}
return (args) => (Math.random() < prob && c.hasOwnProperty(args)
&& c[args]) || (c[args] = f(args))
};
const doThing = (param1) = cache((param1) => {
console.log(`called with param ${param1}`)
return Math.random()
},.1)
console.log(doThing("christian"))
console.log(doThing("christian"))
console.log(doThing("bongiorno"))
执行1:
called with param christian
0.7340898868131249
0.7340898868131249
called with param bongiorno
0.3708897404988516
执行n:
0.6886668809537186
called with param christian
0.5845787434396792
called with param bongiorno
0.2618603367580965