setTimeout внутри функции завершается ошибкой - PullRequest
0 голосов
/ 25 марта 2012

Эта функция принимает аргумент whichImage. Это объект HTMLImageElement для изображения, с которым мы работаем. Ширина изображения будет уменьшена вдвое, а затем через 3 секунды она вернется к нормальной ширине. Однако код setTimeout, который должен выполняться через 3 секунды, завершается ошибкой с сообщением об ошибке, которое whichImage не определено. Что мне нужно исправить, чтобы эта функция работала?

function resizeImageFunction(whichImage){
    // Get the width of the image
    alert(whichImage);
    var width = whichImage.width;
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;
    setTimeout("whichImage.width=width;",3000);
}

Ответы [ 5 ]

1 голос
/ 25 марта 2012

Объяснение вашей проблемы следующее:

Когда вы передаете строку в setTimeout(), эта строка будет оцениваться как eval() в глобальной области видимости. Таким образом, любая функция, которую вы вызываете или переменная, на которую вы ссылаетесь, должна быть доступна из глобальной области видимости. Это объясняет, почему вы не можете ссылаться на локальную переменную или аргумент в своей функции, потому что ни те, ни другие не входят в глобальную область видимости, поэтому, когда eval() пытается их найти, он ищет в глобальной области видимости, а их там нет.

Когда вы меняете функцию setTimeout() на эту, используя встроенную анонимную функцию:

setTimeout(function() {
    whichImage.width = width;
}, 3000);

теперь у вас есть реальный код javascript (не строка), который оценивается там, где он существует без использования eval(), и из-за замыканий у вас есть полный доступ к локальным переменным и аргументам включающей функции, которая дает вам доступ к whichImage (аргумент) и width (локальная переменная), так что ваш код работает.

Это причина № 14, по которой вы всегда должны использовать реальные ссылки на функции javascript или объявления анонимных функций вместо передачи строки в setTimeout().

1 голос
/ 25 марта 2012
function resizeImageFunction(whichImage){
    // Get the width of the image
    alert(whichImage);
    var width = whichImage.width;
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;

    setTimeout(function(){
        whichImage.width=width;
    },3000);
}
0 голосов
/ 25 марта 2012

Вам не нужно использовать eval для этого

setTimeout(function() { whichImage.width=width; } ,3000);

Вот ваша функция

function resizeImageFunction(whichImage){
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;
    setTimeout(function() { whichImage.width=width; } ,3000);
}
0 голосов
/ 25 марта 2012

Попробуйте:


setTimeout(function() {
   whichImage.width=width;
},3000);   
0 голосов
/ 25 марта 2012

Вам нужно обернуть свой блок кода в анонимную функцию, например:

setTimeout(function () {
    whichImage.width=width;
}, 3000);
...