2012-11-19 75 views
0

由於性能和其他問題,我想將代碼拆分爲單獨的函數,就像之前它只是一個大的「.ready」函數。將代碼拆分爲函數

我是新來的javaScript/jquery,但我想我會給它一個自己去。我已經完成了我認爲完成的方式,但是我的控制檯告訴我事情沒有定義,所以我猜測我已經找到了範圍之外的東西。我已經詳細閱讀了它,但還沒有得到任何地方。

我的代碼現在工作正常,但我想進入乾淨的編碼習慣。有人能指出我出錯的地方,所以我可以繼續自己嗎?

這裏是我到目前爲止

//Global variables 
var randomWord = []; 
var listOfWords = []; 
var populationNumber = []; 
var attemptNumber = []; 
var completionNumber = []; 
var gridSize = []; 

generateGrid(); 

startMusic(); 

randomizeReward(); 


//Click event to start the game 
$(".start-btn-wrapper").click(function() { 
    startplay(); 
}); 
//Click event to restart the game 
$(".restart-btn").click(function() { 
    restartplay(); 
}); 

感謝

爲例

小提琴:http://jsfiddle.net/QYaGP/

撥弄HTML:http://jsfiddle.net/QYaGP/1/

+0

在沒有HTML的jsfiddle中沒有一個完整的工作示例,但我的直接猜測是這樣的:你是「全局作用域」變量只是全局的就緒狀態。就緒之外的功能無法訪問這些變量。將它們移到jquery'ready'函數之上,這樣它們就是真正的全局函數,其他函數可以訪問它們。 –

+0

好的我會嘗試Eli Gassert – IronSpoon

+0

瞭解JavaScript變量範圍並閱讀有關[函數式編程](http://eloquentjavascript.net/chapter6.html) –

回答

0

你需要開始傳遞一些信息到你正在定義的功能。如果你的函數都沒有參數,那麼你將不得不使用全局定義的變量,對jquery選擇的硬編碼引用等來完成任何事情。

因此,作爲一個例子,你有一個函數

function replaySound() { 
    $("#hintSound").attr('src', listOfWords[randomWord].hintSound); 
    hintSound.play(); 
} 

這實際上是要通過部件#hintSound發揮listOfWords[randomWord]詳細的聲音。你可以做到這一點通過:

function playSound(selector, wordlistEntry) { 
    $(selector).attr('src', wordlistEntry.hintSound); 
    $(selector)[0].play(); 
} 

然後,而不是調用replaySound(),你會打電話:

playSound('#hintSound', listOfWords[randomWord]); 

這樣,行爲要在功能包裹起來,但細節,即您需要的數據,通過參數傳入。這允許您重複使用該功能來使用任何選擇器播放任何聲音,而不僅僅是#hintSound

你會發現,你需要開始選擇一個函數在調用它的代碼中執行的操作,而不是在函數中。這很好,因爲你想要實現的上下文是在調用代碼中,而不是在函數中。這被稱爲「分離關注」;你試圖將關於某個事物的邏輯限制在一個區域內,而不是將它散佈在許多功能中。但是你仍然希望函數允許你封裝行爲。這允許您乾淨而輕鬆地改變行爲,而不必在每次邏輯改變時重寫所有內容。

結果應該是你發現幾個函數實際上做了同樣的事情,但具有不同的細節,所以你可以只有一個函數,並重用它。那就是不要重複自己的原則,這也很重要。

+0

你能給我舉一個例子嗎? @Phil H – IronSpoon

0

如果你關心性能,我會考慮使用諸如AngularJS之類的框架。您可以注入模塊化代碼。更妙的是,使用MVC,您的視圖將綁定到您的模型,因此通過更改模型視圖會自動更新自身。

此外,停止使用類選擇器。使用ID選擇器。他們要快得多。您還希望預加載選擇器(即使使用類選擇器)。這樣,你只搜索DOM一次:

var ele = $('#elementId'); 

$(ele).doSomething(); 

這樣,你有一個DOM元素的引用。您可以使用一個數據結構到所有引用的存儲在全球範圍之外:

var elementReferences = {}; //declaration 
elementReferences.mainPage = {}; //use 
elementReferences.mainPage.root = $('#mainPage'); //load the root div of a page segment 
elementReferences.mainPage.title = $(elementReferences.mainPage.root).children('#title'); //load the title 

elementReference.mainPage.form = $(elementReferences.mainPage.root).children('#form'); //load the form 

現在你可以這樣做:

$(elementReference.mainPage.form).whatever(); 

,它並沒有搜索DOM的元素。這對大型應用程序特別有用。

如果你把一個函數放在document.ready中,就像你的小提琴那樣,你只能在document.ready調用的範圍內訪問那個函數。您真的希望能夠根據需要在需要的範圍內動態加載/卸載函數,這是angularjs發揮作用的地方。

大部分情況下,您也希望從全局範圍中刪除函數和變量,並將它們放入按其相關性和使用進行排序的容器中。這是面向對象的編程101而不是有一堆陣列坐在全球範圍內,他們可能誤其他開發人員覆蓋範圍內的,你想把它們放在一個容器內:

var arrays = {}; //create the object 

arrays.whatever1 = []; 
arrays.whatever2 = []; 

很明顯,你會可能需要比「數組」更具描述性的名稱。功能的工作方式相同:

var ajax = {}; //ajax object 
var ajax.get = function(){ 
}; 
var ajax.post = function(){ 
}; 
var ajax.delete = function(){ 
}; 

這通常會促進更清潔的代碼更易於重用和維護。您希望花大量時間編寫一個規範,在實際開始開發之前完整記錄整個體系結構。如果你能幫助它,永遠不要跳槍。花時間徹底研究和規劃大局,以及如何將所有東西放在一起,而不是試圖將它展現出來,並且隨時隨地解決問題。當你這樣做時,你花更少的時間不得不重新發明輪子。

它是由谷歌開發的,所以它應該在相當長一段時間。我不確定你是否是負責系統架構的人,但如果性能/可重用性是貴公司的問題,那麼絕對值得一看。我非常樂意爲您提供關於軟件架構和工程方面大部分知識的演練。如果你有興趣,就試試我吧。總是樂於幫助!