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/

4

2 回答 2

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(){
};

这通常会促进更简洁的代码,这些代码更可重用且更易于维护。您希望在实际开始开发之前花费大量时间编写一个完整记录整体架构的规范。如果你能帮上忙,千万不要急于求成。花时间彻底研究和规划大局以及一切如何组合在一起,而不是试图随心所欲地解决它。当你这样做时,你花更少的时间重新发明轮子。

它是由 google 开发的,所以它应该已经存在了一段时间。我不确定您是否是负责系统架构的人,但如果性能/可重用性是您公司的一个问题,那么绝对值得一看。我非常乐意向您介绍我在软件架构和工程方面所知道的大部分内容。如果你有兴趣,就给我留言。总是乐于助人!

于 2012-11-19T16:51:04.403 回答
0

您需要开始将一些信息传递到您定义的函数中。如果您的函数都没有参数,那么您将不得不使用全局定义的变量、对 jquery 选择的硬编码引用等才能完成任何事情。

举个例子,你有一个功能

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

这实际上是listOfWords[randomWord]通过 element播放详细的声音#hintSound。您可以通过以下方式做到这一点:

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

然后你会打电话而不是replaySound()打电话:

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

这样,您想要的行为被包含在函数中,但是细节,即您需要的数据,是通过参数传入的。这允许您重用该功能以使用任何选择器播放任何声音,而不仅仅是#hintSound.

当您这样做时,您会发现您需要开始选择函数将在调用它的代码中执行的操作,而不是在函数中。这很好,因为您尝试实现的上下文存在于调用代码中,而不是函数中。这被称为“关注点分离”;您尝试将给定事物的逻辑限制在一个区域,而不是将其分散在许多功能中。但是您仍然希望函数允许您封装行为。这使您可以干净而轻松地更改行为,而不必在每次逻辑的某些部分更改时都重写所有内容。

结果应该是你发现几个函数实际上做了同样的事情,但细节不同,所以你可以只使用一个函数并重用它。这就是不要重复自己的原则,这也很重要。

于 2012-11-19T16:32:13.307 回答