这里有一个解决方案和一个推荐的替代方案;两者都使用<function>.bind(<this>[,<arg1>][,<arg2>])
bind
包装了预期的函数,并使用附加指定参数(args)对其进行调用。 bind
的第一个参数将是函数的this
实例。将其设置为undefined
将传递原始的this
实例。
匿名函数。
var settings;
for(i = 0; i < tiles.length; i++)
{
settings = {};
settings.sourceX = tiles[i][5];
settings.sourceY = tiles[i][6];
settings.sourceWidth = tiles[i][9];
settings.sourceHeight = tiles[i][10];
settings.destWidth = sourceWidth;
settings.destHeight = sourceHeight;
settings.destX = tiles[i][7];
settings.destY = tiles[i][8];
settings.imageObj = new Image();
settings.imageObj.onload = function(args)
{
context.drawImage(args.image, args.sourceX, args.sourceY, args.sourceWidth, args.sourceHeight, args.destX, args.destY, args.destWidth, args.destHeight);
}.bind(undefined, settings);
settings.imageObj.src = tiles[i][4];
}
虽然我不喜欢使用匿名函数来处理常见事件,但我更倾向于声明一个对象来存储处理程序。
这样你就可以在运行时替换处理程序。像下面这样的方式。
声明对象以存储事件处理函数
var Handlers = {
"drawImageHandler" : function drawImageHandler(args)
{
context.drawImage(args.image, args.sourceX, args.sourceY, args.sourceWidth, args.sourceHeight, args.destX, args.destY, args.destWidth, args.destHeight);
}
};
function DebugInit()
{
var func = Handlers.drawImageHandler;
Handlers.drawImageHandler = function(func, args) {
console.log("%o", args);
func(args);
}.bind(undefined, func);
}
var settings = {};
DebugInit();
for(i = 0; i < tiles.length; i++)
{
settings = {};
settings.sourceX = tiles[i][5];
settings.sourceY = tiles[i][6];
settings.sourceWidth = tiles[i][9];
settings.sourceHeight = tiles[i][10];
settings.destWidth = sourceWidth;
settings.destHeight = sourceHeight;
settings.destX = tiles[i][7];
settings.destY = tiles[i][8];
settings.imageObj = new Image();
settings.imageObj.onload = Handlers.drawImageHandler.bind(undefined, settings);
settings.imageObj.src = tiles[i][4];
}
jsFiddle: 示例 Fiddle
context.drawImage
方法的值仍然超出了作用域范围。也就是说,sourceX
,sourceY
等在每个imageObj
(或this
)实例上都很可能等同于tiles [tiles.length-1]
。 - Brett Caswell