2012-01-12 4 views
2

У меня есть следующая функцияУстановить переменную в другом контексте

"use strict"; 
function Player 
{ 
    this.width; 
    this.height; 
    this.framesA = 5; 

    this.image = new Image(); 
    this.image.onload = function() 
    { 
     width = this.width; 
     height = this.height/framesA; 
    } 
    this.image.src = "Images/angel.png"; 
} 

Как я могу сделать этот код работать?
Я хочу, чтобы ширина и высота в функции Player были проиндексированы с шириной и высотой изображения при вызове функции onload.

Мне нужно это, чтобы работать со строгим режимом (обязательно).

Если это нужно сделать другим способом, не стесняйтесь учить.

EDIT: Я обновил код, чтобы отразить более реалистичную ситуацию (я не знаю, что это будет настолько сложным)

EDIT 2: Другого обновления кода. Я не заметил, что я написал var insted этого. Сожалею.

Заранее спасибо

+4

Просто используйте '' this.image.width' и this.image. height' ... –

+0

Ваш пример должен работать, я думаю, в чем проблема? –

+0

@ Šime Vidas Мне нужно сохранить значение, так что решение будет априорировано –

ответ

2

Что я собрал из ваших комментариев, так это то, что вы хотите иметь доступ к ширине и высоте вне функции Player, и проблема в том, что вы не знаете, когда доступны ширина и высота.

Если это правильно, это становится немного сложнее. Поскольку вы не знаете, когда изображение будет загружено и не будет иметь ширину и высоту перед загрузкой (если вы не укажете их в стороне сервера img), вам необходимо использовать функцию, которая выполняет обратный вызов для доступа ширины и высоты игрока.

В принципе, если ширина и высота еще не известны, функция просто возвращает обратный вызов в очередь. Когда определяются ширина и высота, все функции в очереди вызываются с передачей им ширины и высоты в качестве аргументов. Если размеры уже известны при вызове функции, она должна сразу же вызвать функцию обратного вызова с правильными аргументами.

Вот как я это сделать:

function Player() { 
    'use strict'; 

    // Store this in a variable so the onload handler can see it. 
    var that = this; 
    var callbacks = []; 

    this.frames = 5; 

    this.getDimensions = function (callback) { 
     // We don't have the dimensions yet, so put the callback in the queue. 
     callbacks.push(callback); 
    }; 

    this.image = new Image(); 
    this.image.onload = function() { 
     var width = this.width; 
     var height = this.height/that.frames; 

     // Call each of the registered callbacks. 
     var i; 
     for (i = 0; i < callbacks.length; i += 1) { 
      callbacks[i](width, height); 
     } 
     // Don't keep unnecessary references to the functions. 
     callbacks = null; 

     // We now know the dimensions, so we can replace the getDimensions 
     // function with one that just calls the callback. 
     that.getDimensions = function (callback) { 
      callback(width, height); 
     }; 
    }; 
    this.image.src = "Images/angel.png"; 
} 

А вот как вы бы получить доступ размеры:

var p = new Player(); 
p.getDimensions(function (width, height) { 
    console.log("Player's width is " + width + " and height is " + height); 
}); 
+0

Только 1 вопрос: var что = это копируется (по значению) или копируется адрес памяти (по refrence)? –

+1

@RandallFlagg, 'that' и' this' указывают на тот же объект, он не копируется. –

2

Просто установите переменные и сделать ваши манипуляции внутри onload события, и они будут оставаться в области.

"use strict"; 
function Player 
{ 
    this.image = new Image(); 
    this.image.src = "Images/angel.png"; 
    this.image.onload = function() 
    { 
     var width = this.width; 
     var height = this.height; 
     // Do your manipulations within the `onload` event. 
    } 
} 
+0

yikes, определенно не то, что просит OP, будет много игроков, вы не можете разделить ширину –

+1

Ваш второй пример не будет работать, потому что изображение не будет загружено (если оно не кэшировано), когда вы вызываете 'width = this.image.width'. Чтобы этот подход работал, вам нужно дождаться события onload. –

+0

@Juan, вы правы! Я изначально ошибочно принимал «Игрок» за стандартный метод. Я исправил одиночное решение, чтобы использовать событие onload и выполнять манипуляции изнутри. –

0

Вот что на самом деле означает Šime Vidas

"use strict"; 
function Player { 
    this.image = new Image(); 
    this.image.src = "Images/angel.png"; 
} 

Player.prototype.getWidth = function() { 
    return this.image.width; 
} 

или, если вам нравится объектов на основе закрытия

function Player { 
    this.image = new Image(); 
    this.image.src = "Images/angel.png"; 
    this.getWidth = function() { 
     return this.image.width; 
    } 
} 
+0

. Для этого подхода к работе вам нужно дождаться события onload ... –

+0

Нет вы не ... Он просто не будет доступен, пока он не будет загружен. Как и в вашем случае, 'ширина 'не будет определена до загрузки изображения. –

0

Этот вариант проходит через JSLint без каких-либо проблем, а также хорошо работает. Так в чем проблема?

function Player() { 
    "use strict"; 
    var width, height; 
    this.image = new Image(); 
    this.image.onload = function() { 
     width = this.width; 
     height = this.height; 
    }; 
    this.image.src = "Images/angel.png"; 
} 

Обратите внимание, что вы должны поместить «использовать строгий»; внутри функции, а не снаружи.

+0

A. Я знаю, что это проходит через JSLint B. Весь мой код строгий, поэтому нет необходимости помещать его в функцию, потому что он используется во всем файле C. Проблема в том, что если вы протестируете его в браузере, который поддерживает строгий режим (я тестирую на Chromium), вы увидите, что ширина и высота не ограничены. –

+0

Прошу прощения, но я ввел вас в заблуждение. ширина и высота - это свойства Player и не определены как var. Я обновил свой код. –

Смежные вопросы