2016-06-12 61 views
0

我發現自己越來越多地寫了下面的JavaScript,我想知道這是否是一種常見的模式,如果是這樣,它叫什麼?的代碼和圖案的這是一個有效的模式,它叫什麼?

部分:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function() { 
    var _index = 0, 
     _numberOfFruits = fruits.length; 

    getNextFruit = function() { 
     render(fruits[_index]); 
     _index = (_index + 1) % _numberOfFruits; 
    } 
    getNextFruit(); 
}; 

我有一個函數,沒有參數,我重新定義函數,並立即調用它的函數的內部。在函數式語言中,這可能是一個返回的函數,JavaScript使得它更容易,因爲您可以重用函數的名稱。因此,您可以擴展功能而無需更改您的實施。

我也可以想象這種模式對於記憶是非常有用的,你的「緩存」是我們環繞的狀態。

我甚至有時在函數中使用getset方法實現此功能,如果它有意義,我可以獲得該狀態。添加的小提琴顯示了一個例子。

因爲這是一個主要的JavaScript面向問題:The obligatory fiddle

+0

不確定渲染是什麼,但一個接一個地「生成」一個集合的元素而不關心底層數據類型稱爲[iterator](https://en.wikipedia.org/wiki/Iterator_pattern)模式。 –

+1

該模式被稱爲「自定義函數」,該名稱已在Stoyanov的書「Javascript Patterns」中介紹過。 –

+0

爲什麼不在函數中定義'fruits'變量和數組? – nnnnnn

回答

2

我有一個函數,它不帶任何參數,我重新定義功能,並立即把它裏面的功能。 這是一個有效的模式,它叫什麼?

重新定義自身的函數通常是一個反模式,因爲它會讓很多東西變得複雜。是的,換掉整個功能有時可能比將if (alreadyInitialised)條件放入功能更有效,但它很少值得。當您需要優化性能時,您可以嘗試對兩種方法進行基準測試,但其他建議是儘可能保持簡單。

模式「在第一次調用時自行初始化」被稱爲laziness,用於純計算(在函數式編程中)和作爲對象(在OOP中)的singleton

但是,大多數時候沒有理由推遲對象/函數/模塊的初始化,直到第一次使用。爲它所用的資源(包括時間和內存)是微不足道的,特別是當你確信你至少需要在你的程序中需要它時。爲此,請在JavaScript中使用IIFE,在創建對象時也稱爲module pattern

+0

我需要更多的時間來真正包圍我這個懶惰概念以及它如何應用於JavaScript。我認爲你可能是對的,這意味着這是一個懶惰的實現。 –

1

通過封閉創建一個功能是在JavaScript中一個很常見的模式。我會親自做的是不同的:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function(fruits) { 
    var index = 0, 
     numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
}(fruits); 

有沒有很好的理由(在我看來),因爲他們是私有的,封閉反正弄亂與領先的下劃線的變量名。上面也沒有將閉包的工作與外部變量名稱耦合起來。我的版本可以製成一個可重用的服務:

function fruitGetter(fruits) { 
    var index = 0, numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
} 

// ... 

var getNextFruit = fruitGetter(someFruits); 

var otherFruits = fruitGetter(["kumquat", "lychee", "mango"]); 
+0

對於下劃線你是絕對正確的,除了我通常使用的一些奇怪的「編碼標準」之外沒有什麼好的理由。使重構更容易,不會錯過變量。要回到這個問題,關閉是一種模式嗎?或者僅僅是一種語言功能? –

+1

「閉包」是一種語言功能。這是創建和維持「對象」的術語,用於保存在調用函數返回函數(如代碼中)時「捕獲」的局部變量。 – Pointy

+0

如果你想使用下劃線,那麼請這樣做,並感覺良好。他們只是煩我:) – Pointy