2015-12-23 4 views
0

Я пытаюсь реорганизовать некоторый код, и у меня возникает проблема, когда глобальная переменная определяется должным образом в одной части функции конструктора объекта, но не определена в другой части ту же функцию.глобальная переменная javascript становится неопределенной внутри части конструктора объекта

Я определил некоторые глобальные переменные следующим образом:

$(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 - open the console to see the messages

+1

, когда вы сохраняете ширину и высоту, изображение еще не загрузилось ... Асинхронный процесс, поэтому у вас есть события загрузки ... – epascarello

+1

вы не можете определить глобальные переменные, используя 'var' в функции. переместите объявление за пределы готовой() или используйте 'window.imgWidth = x' для создания глобальной функции внутри функции. – dandavis

+0

Выполняется ли ваш код внутри '$ (document) .ready (function() {/ * здесь * /})'? – PHPglue

ответ

2

Причина, по которой становится «неопределенным», потому что вы установите переменную 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; 

На данный момент hasnt 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); 
}); 
0

Если вы хотите, чтобы объявить и использовать глобальную переменную области видимости, я думаю, что один из лучших способов, чтобы быть супер ясно об этом:

window.someGlobalVariable = 4;

Проблема, с которой вы столкнулись, заключается в том, что вы фактически не находитесь в глобальной области действия, а в области функций. если быть точным: в обратном вызове на DOM-ready.

0

Это должно продемонстрировать проблемы с локальными и глобальными переменными Область применения:

// 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