2016-11-28 158 views
4

我曾經有過類似下面的...將函數賦值給javascript中的變量?

var setFoo = function (value1) { 
    window.localStorage.setItem('foo1', value1); 
} 

var setFoo2 = function (value2) { 
    window.localStorage.setItem('foo2', value2); 
} 

。但是,我發現,我經常做...

window.localStorage.setItem('something', value); 

......所以我決定把它成函數...

function genericSetFoo(name, value) { 
    window.localStorage.setItem(name, value); 
} 

...並已取代以下...

var setFoo = genericSetFoo('foo1', value1); 
var setFoo2 = genericSetFoo('foo2', value2); 

...但是,現在當我嘗試撥打setFoo1(value1)setFoo2(value2)時,申請投訴value1value2undefined。我究竟做錯了什麼?我的意思是我仍然可以做...

var setFoo = function(value1) { genericSetFoo('foo1', value1) }; 
var setFoo2 = function(value2) { genericSetFoo('foo2', value2) }; 

...和它的作品太...但它違背了整點,如果我要重新在任何情況下的功能。那麼我該如何解決這個問題呢?

回答

1

我在做什麼錯?

你打電話給window.localStorage.setItem()而不是返回一個函數,調用window.localStorage.setItem()。請記住,當您調用一個函數並將其分配給一個變量時,您正在爲該函數分配的返回值,而不是函數本身。

例如,當你這樣做:

function a() { return 2 }; 

var two = a(); 

..你所期望的變量two2或功能?另外一個例子,如果你這樣做:

var x = document.getElementById('foo'); 

..你所期望的變量x包含一個DOM元素或功能?

所以,你需要返回一個函數,而不是調用一個函數:

function genericSetFoo(name) { 
    return function (value) { 
     window.localStorage.setItem(name, value); 
    } 
} 

所以現在你可以這樣做:

var setFoo1 = genericSetFoo('foo1'); 
+0

哦,謝謝。這真的很有趣。這似乎是我目前理解的最易理解的解決方案。然而,其他一些用戶已經提到了一些關於「咖喱」或「部分應用」的內容......與此相比,你對此有何評論?讚賞。 – Grateful

+0

好的,我剛剛意識到你的方法實際上也是一個咖啡的例子。但是,這是如何推遲'.bind'技術的呢? – Grateful

+0

@Grateful:這不需要額外的語言功能(如ES5'.bind()'),並且可以一直回到原始的Netscape版本的JavaScript和IE的jscript原始版本。另外,一旦你瞭解了函數和閉包的工作方式,你可以自己實現其他的語言特性,例如'.bind()'。 – slebetman

2

在這種情況下,您可以使用.bind()。這種技術被稱爲「局部功能評價」:

var setFoo = genericSetFoo.bind(null, 'foo1'); 
var setFoo2 = genericSetFoo.bind(null, 'foo2'); 

setFoo(value1); 

如果您使用lodash或下劃線,你可以使用_.partial()這是.bind不同,它不要求第一個參數,不重新綁定this值:

var setFoo = _.partial(genericSetFoo, 'foo1'); 
var setFoo2 = _.partial(genericSetFoo, 'foo2'); 
1

我做錯了嗎?

當你這樣做:

var setFoo = genericSetFoo('foo1', value1); 

要調用genericSetFoo()和分配從它返回setFoo值。但由於value1undefined在初始化setFoo時(因此調用genericSetFoo()),因此window.localStorage.setItem(name, value)試圖使用傳遞給它的參數value參數的參數時會出現undefined錯誤。