Javascript 将模块模式与闭包相结合的最佳方法
我目前正在尝试实现一些常见的JS概念 在小项目中更好地理解如何使用它们 我一直在做一个简单的游戏,试图 理解并使用模块模式和闭包。 我使用的是Stoyan Stefanov的“模式”中的模块模式 书 我正在努力理解如何最好地混合模块和 关闭 我想知道我是否在组织以下代码 明智的方法?如果是这样,我的问题是:什么是最好的方式 修改代码,以便在Javascript 将模块模式与闭包相结合的最佳方法,javascript,design-patterns,closures,Javascript,Design Patterns,Closures,我目前正在尝试实现一些常见的JS概念 在小项目中更好地理解如何使用它们 我一直在做一个简单的游戏,试图 理解并使用模块模式和闭包。 我使用的是Stoyan Stefanov的“模式”中的模块模式 书 我正在努力理解如何最好地混合模块和 关闭 我想知道我是否在组织以下代码 明智的方法?如果是这样,我的问题是:什么是最好的方式 修改代码,以便在$(function(){})中 是否可以访问update()函数 MYAPP.utilities = (function() { return {
$(function(){})
中
是否可以访问update()
函数
MYAPP.utilities = (function() {
return {
fn1: function(lives) {
//do stuff
}
}
})();
MYAPP.game = (function() {
//dependencies
utils = MYAPP.utilities
return {
startGame: function() {
//initialisation code
//game state, stored in closure
var lives = 3;
var victoryPoints = 0;
function update(){
utils.fn1(lives);
//do other stuff
}
}
}
})();
$(function(){
MYAPP.game.startGame();
//Want to do this, but it won't work
//because I don't have access to update
$('#button').on('click',MYAPP.game.update)
});
我想出了几个可行的办法,但是
我想知道它们是否是好的做法,最好的做法是什么
选择是
选项:
(1) 绑定$(“#按钮”)。在('click',…)
上作为
StartName初始化代码
(2) 将update()
函数分配给一个变量,然后
从startGame函数返回此变量,因此
$(function(){})
我们可以
updatefn=MYAPP.game.startGame()代码>然后
$(“#按钮”)。在('click',MYAPP.game.update)
(3) ??有更好的办法吗
非常感谢您的帮助
Robin首先,要以这种方式访问update
函数,它必须在返回的对象中公开
return {
update: function() {
[...]
},
startGame: function() {
[...]
this.update();
}
}
调用obj.method()。也就是说,调用MYAPP.game.startGame()
将this
设置为MYAPP.game
方法调用中的startGame
。有关此行为的更多详细信息
您还需要将lifes
变量移动到一个公共范围,该范围可由startGame
和update
方法访问,这正是闭包的目的:
MYAPP.game = (function() {
[...]
var lives; //private/privileged var inside the closure, only accessible by
//the returned object's function properties
return {
update: function() {
utils.fn1(lives);
},
startGame: function() {
[...]
lives = 3; //sets the closure scope's lives variable
[...]
this.update();
}
}
})();
在这种情况下,您需要一些方法来设置lifes
变量。另一种方法是将lifes
变量作为返回对象的属性,并通过方法内部的this.lifes
对其进行访问,从而使其成为公共变量
注意:如果只传递对函数对象的引用,该函数对象存储为返回对象的属性,如中所示:
$('#button').on('click', MYAPP.game.update);
单击处理程序中的this
引用将不指向MYAPP.game
,因为传递的函数引用将直接从jQuery核心调用,而不是作为对象的成员函数调用-在这种情况下,此
将指向#按钮
元素,因为jQuery事件处理程序将此
引用设置为触发处理程序的元素,如您所见
要补救,您可以使用:
或者旧的函数包装技巧:
$('#button').on('click', function() {
MYAPP.game.update(); //called as method of an obj, sets `this` to MYAPP.game
});
当在更新
方法中使用此
关键字时,这一点很重要。代码中存在一些问题。首先,update()
函数在动态创建的对象外部不可见。要使它成为游戏
对象的一部分,它必须与开始名
处于同一级别
另外,如果您声明var lifes=3
,它将是一个局部变量,并且在startGame()
函数以及victoryPoints
之外不可见。这两个变量必须以某种方式可见(通过闭包或作为对象字段)
最后,作为事件侦听器附加MYAPP.game.update
将只附加该函数,从而阻止您使用所有其他对象方法/函数。根据您想要执行的操作,您可能更愿意传递一个闭包,比如function(){MYAPP.game.update()}
您的代码应该如下所示:
MYAPP.utilities = (function() {
return {
fn1: function(lives) {
console.log(lives);
}
}
})();
MYAPP.game = (function() {
//dependencies
utils = MYAPP.utilities
var lives;
var victoryPoints;
return {
startGame: function() {
//initialisation code
//game state, stored in closure
lives = 3;
victoryPoints = 0;
},
update: function() {
utils.fn1(lives);
//do other stuff
}
}
})();
$(function(){
MYAPP.game.startGame();
//Want to do this, but it won't work
//because I don't have access to update
$('#button').on('click', MYAPP.game.update)
});
()谢谢-这很有道理
MYAPP.utilities = (function() {
return {
fn1: function(lives) {
console.log(lives);
}
}
})();
MYAPP.game = (function() {
//dependencies
utils = MYAPP.utilities
var lives;
var victoryPoints;
return {
startGame: function() {
//initialisation code
//game state, stored in closure
lives = 3;
victoryPoints = 0;
},
update: function() {
utils.fn1(lives);
//do other stuff
}
}
})();
$(function(){
MYAPP.game.startGame();
//Want to do this, but it won't work
//because I don't have access to update
$('#button').on('click', MYAPP.game.update)
});