x86 с использованием петель, чтобы минимизировать код (подкладка) [дублировать]

Это описывает распространенную ошибку с использованием замыканий в JavaScript.

Функция определяет новую среду

. Рассмотрим:

function makeCounter()
{
  var obj = {counter: 0};
  return {
    inc: function(){obj.counter ++;},
    get: function(){return obj.counter;}
  };
}

counter1 = makeCounter();
counter2 = makeCounter();

counter1.inc();

alert(counter1.get()); // returns 1
alert(counter2.get()); // returns 0

Для каждого времени makeCounter, {counter: 0} приводит к созданию нового объекта. Кроме того, создается новая копия obj для ссылки на новый объект. Таким образом, counter1 и counter2 не зависят друг от друга.

Замыкания в циклах

Использование замыкания в цикле является сложным.

Рассмотрим:

var counters = [];

function makeCounters(num)
{
  for (var i = 0; i < num; i++)
  {
    var obj = {counter: 0};
    counters[i] = {
      inc: function(){obj.counter++;},
      get: function(){return obj.counter;}
    }; 
  }
}

makeCounters(2);

counters[0].inc();

alert(counters[0].get()); // returns 1
alert(counters[1].get()); // returns 1

Обратите внимание, что counters[0] и counters[1] независимы не . Фактически, они работают на одном и том же obj!

Это связано с тем, что есть только одна копия obj, разделенная на все итерации цикла, возможно, по соображениям производительности. Несмотря на то, что {counter: 0} создает новый объект на каждой итерации, одна и та же копия obj будет просто обновляться с ссылкой на самый новый объект.

Решение состоит в использовании другой вспомогательной функции:

function makeHelper(obj)
{
  return {
    inc: function(){obj.counter++;},
    get: function(){return obj.counter;}
  }; 
}

function makeCounters(num)
{
  for (var i = 0; i < num; i++)
  {
    var obj = {counter: 0};
    counters[i] = makeHelper(obj);
  }
}

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

Подробное обсуждение см. в JavaScript ловушки закрытия и использование

0
задан Dfarrelly 15 May 2016 в 21:20
поделиться

1 ответ

Как предложил Питер Кордес, я представляю данные как шестнадцатеричные значения:

RR RR RR RR EE EE HH LL
|           |     || ||
|           |     || AL
|           |     AH  |
|           |     |___|
|           |     AX  |
|           |_________|
|           EAX       |
|_____________________|
RAX

... где RAX - 64-битный регистр, который существует в x86-64.

Итак, если у вас были AH = 0x12 и AL = 0x34, вот так:

00 00 00 00 00 00 12 34
|           |     || ||
|           |     || AL
|           |     AH  |
|           |     |___|
|           |     AX  |
|           |_________|
|           EAX       |
|_____________________|
RAX

... тогда у вас были AX = 0x1234 и EAX = 0x00001234 и т. д.

Обратите внимание, что, как показано на этой диаграмме, AH является единственным «странным» регистром, который не согласован с нижними битами. Остальные (AL, AX, EAX, RAX для 64-битных) имеют разные размеры, но все выровнены справа. (Например, два байта, отмеченные EE EE на диаграмме, сами не имеют имени регистра.)

3
ответ дан CherryDT 26 August 2018 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: