我正在尝试重构一些代码,但遇到了一个问题,即全局变量在对象构造函数的一部分中正确定义,但在同一函数的另一部分中未定义。
我定义了一些全局变量如下:
$( document ).ready(function() {
var imgWidth;
var imgHeight;
然后我写了一个对象构造函数。最终目标是为图像创建一个对象,该对象包含:实际图像对象、宽度(定义为实际图像宽度/2)、高度(定义为真实图像高度/2)、x位置(手动指定)和y位置(手动规定)。
function Character(name, x, y){
//define the image object within the Character
this.imageObject = new Image();
//using base-64 encoded data in place of an image url, just for the demo
this.imageObject.src = name+'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAW0lEQVR42mL8//8/AzpgZGTcC6KBcs5wMRwK/0MVMsLEmLAoEmXAApiwiKUhaRJCltgLsQVsWwIQ/wTx0fBeRigD7B6Y24i1mj4Kn4KI7Uie2Y7FI8+B2AMgwABjRynfWgpcxQAAAABJRU5ErkJggg==';
console.log(this.imageObject);
console.log(this.imageObject.src);
//set natural width and natural height once the image is loaded
if (this.imageObject.addEventListener){
this.imageObject.addEventListener('load', function(){
console.log('this.naturalWidth for '+this.src+' = '+this.naturalWidth);
window.imgWidth = this.naturalWidth/2;
window.imgHeight = this.naturalHeight/2;
console.log('imgWidth inside imageObject event listener for '+this.src+' = '+window.imgWidth);
});
} else if (this.imageObject.attachEvent){
this.imageObject.attachEvent('onload', function(){
console.log('this.naturalWidth for '+this.src+' = '+this.naturalWidth);
window.imgWidth = this.naturalWidth/2;
window.imgHeight = this.naturalHeight/2;
console.log('imgWidth inside imageObject event listener for '+this.src+' = '+window.imgWidth);
});
}
//set natural width and natural height to object
this['w'] = this['w0'] = window.imgWidth;
this['h'] = this['h0'] = window.imgHeight;
//set initial x and y position
this['x'] = x;
this['y'] = y;
console.log('imgWidth inside character constructor = '+window.imgWidth);
}
我这样调用函数,立即在文档内部准备好:
var sun0 = new Character('data:text/javascript;base64,', 1, 0);
在Chrome中检查控制台时,console.log行输出如下:
console.log(this.imageObject); //the image object as expected
console.log(this.imageObject.src); //the image url as expected
console.log('this.naturalWidth for '+this.src+' = '+this.naturalWidth); //10 as expected
console.log('imgWidth inside imageObject event listener for '+this.src+' = '+window.imgWidth); //5 as expected
console.log('imgWidth inside character constructor = '+window.imgWidth); //undefined
为什么此处未定义window.imgWidth?有没有更好的方法来创建这个对象,使其具有w的属性,即图像自然宽度的1/2?
JS Fiddle-打开控制台查看消息
它变为"undefined"的原因是因为您在事件处理程序函数中设置了imgWidth变量,该函数只在将来某个时候执行。事件处理程序函数是异步发生的,也就是说,在未来的某个时刻,程序在事件处理程序声明后继续执行代码。
当声明事件处理程序函数时,在调用onload事件处理程序之前,代码将继续运行并执行这些行:
//set natural width and natural height to object
this['w'] = this['w0'] = window.imgWidth;
this['h'] = this['h0'] = window.imgHeight;
//set initial x and y position
this['x'] = x;
this['y'] = y;
此时,尚未调用(激发)onload事件处理程序,因此运行时环境将正确地报告window.imgWidth未定义。
如果您希望运行此代码,最简单的方法是将以上内容添加到事件处理程序例程中,如下所示:
this.imageObject.attachEvent('onload', function(){
console.log('this.naturalWidth for '+this.src+' = '+this.naturalWidth);
window.imgWidth = this.naturalWidth/2;
window.imgHeight = this.naturalHeight/2;
console.log('imgWidth inside imageObject event listener for '+this.src+' = '+window.imgWidth);
//set natural width and natural height to object
this['w'] = this['w0'] = window.imgWidth;
this['h'] = this['h0'] = window.imgHeight;
//set initial x and y position
this['x'] = x;
this['y'] = y;
console.log('imgWidth inside character constructor = '+window.imgWidth);
});
如果你想声明和使用全局范围变量,我认为最好的方法之一是非常清楚:
window.someGlobalVariable=4;
你似乎遇到的问题是,你实际上不在全局范围内,而是在函数范围内。确切地说:在DOM ready上的回调中。
这应该说明本地和全局范围变量的问题:
// imgWidth hasn't been defined yet
console.log('before ready statement: ' + typeof imgWidth);
$(window).ready(function() {
// here we are defining a local variable named imgWidth
var imgWidth = 100;
});
console.log('after ready statement: ' + typeof imgWidth);
// imgWidth hasn't been defined yet
console.log('before ready statement: ' + typeof imgHeight);
$(window).ready(function() {
// here we are defining a a global variable named imgHeight
window.imgHeight = 200;
});
console.log('after ready statement: ' + typeof imgHeight);
console.log('imgHeight is ' + imgHeight);
输出:
before ready statement: undefined
after ready statement: undefined
before ready statement: number
after ready statement: number
imgHeight is 200