过去我再次遇到过这个问题,并且我使用了全局变量,但我想知道还有其他方法来处理它。
代码来自我现在正在玩的an html5 canvas tutorial。
var x = 150;
var y = 150;
var dx = 2;
var dy = 4;
var ctx;
function init() {
ctx = $('#canvas')[0].getContext("2d");
return setInterval(draw, 10);
}
function draw() {
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
x += dx;
y += dy;
}
init();
我可以做些什么来避免使用全局变量?
答案 0 :(得分:4)
您可以使用模块模式 - 这是一种提供封装的简洁方法:
var app = app || {};
app = (function () {
var x = 150; // all these variables are private
var y = 150;
var dx = 2;
var dy = 4;
var ctx;
var draw = function() { // this method is private
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
x += dx;
y += dy;
};
return {
init: function() { // this method is public
ctx = $('#canvas')[0].getContext("2d");
return setInterval(draw, 10);
}
}
}());
app.init(); // init() is public, but all the other vars and functions are not
在http://addyosmani.com/largescalejavascript/#modpattern了解详情。
答案 1 :(得分:3)
您可以使用对象,如图here
所示myObj = {
x: 150,
y: 150,
dx: 2,
dy: 4,
ctx: null,
init: function() {
this.ctx = $('#canvas')[0].getContext("2d");
return setInterval((function(a){return function(){a.draw()}})(this), 10);
},
draw: function() {
this.ctx.clearRect(0,0,300,300);
this.ctx.beginPath();
this.ctx.arc(this.x, this.y, 10, 0, Math.PI * 2, true);
this.ctx.closePath();
this.ctx.fill();
this.x += this.dx;
this.y += this.dy;
}
}
myObj.init();
重要完全披露,此代码无法正常工作。虽然我支持我的一般方法,但仍需要传递setInterval正确的上下文。我已经修复了我的答案以反映上述内容,并为小提琴链接添加了一个工作示例。如果上下文传递让您感到困惑,请使用其他方法。
答案 2 :(得分:1)
将它们作为参数传递,并将其修改为:
function init() {
var x = 150;
var y = 150;
var dx = 2;
var dy = 4;
var ctx = $('#canvas')[0].getContext("2d");
return setInterval(function() {
var temp = draw(x, y, dx, dy, ctx);
x = temp.x;
y = temp.y;
}, 10);
}
function draw(x, y, dx, dy, ctx) {
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
x += dx;
y += dy;
ret = {};
ret.x = x;
ret.y = y;
return ret;
}
(我不完全确定需要传递什么;如果你能这样做,可以减少传递以减少耦合。)
然而,这个解决方案不如类似于类的方法,例如@Asad提出的方法。
答案 3 :(得分:1)
这很诱人,而且只是把一切都包装在一个对象中,或者一个IIFE来处理全局,这确实很容易,但这并没有给派对带来任何新的东西。我建议一个简单的闭包,其中所有变量都在init
函数内设置。在这个函数中,我们定义draw
函数,以便该函数可以访问闭包变量。由于该函数仅用于设置间隔,因此我省略了名称,因为在此闭包中根本不需要具有命名函数。
var init = function()
{
var x, y, dx, dy, ctx = document.getElementById('canvas').getContext('2d');
return setInterval(function()
{
ctx.clearRect(0,0,300,300);
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
x += dx;
y += dy;
},10);
};
var iv = init();//<-- best off storing the interval somewhere
//... stop drawing:
clearInterval(iv);
这就是它的全部。