[英]Caching a closure in javascript
閱讀問題的答案后: JavaScript 內部函數和性能
我想知道在這種情況下是否可以緩存內部函數(doSomethingCool):
function newUser(user){
function doSomethingCool(){
console.log(user);
}
}
你不能真正緩存一個閉包。 如果這樣做,那么它仍然會關閉它最初定義的函數的變量。
例如,您可能會考慮這樣做,乍一看可能沒問題:
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;
}());
使用閉包的目的是保留創建它的上下文。 如果您“緩存”您的閉包,則對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
但不利用閉包屬性的實用程序函數,則最好移動該函數並接受用戶作為參數。 也就是說,我非常懷疑把它留在那里會以任何明顯的方式影響你的表現。
這是一個使用基本閉包和函數的簡單緩存。 它的驅逐策略是一種基於概率的策略,但您可以輕松地將其修改為基於時間的策略。 與其他一些解決方案不同,這個解決方案不需要你調用 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.