Странный оператор javascript: expr >>> 0

следующая функция предназначена для реализации свойства indexOf в IE. Если вам когда-либо приходилось это делать, я уверен, что вы это видели раньше.

if (!Array.prototype.indexOf){

  Array.prototype.indexOf = function(elt, from){

    var len = this.length >>> 0;
    var from = Number(arguments[1]) || 0;

    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);

    if (from < 0)
      from += len;

    for (; from < len; from++){
      if (from in this &&    
          this[from] === elt)
        return from;
    }

    return -1;    
  };
}

Мне интересно, можно ли использовать три знака выше, чем автор, сделанный при первоначальной проверке длины?

var len = this.length >>> 0

Выполнение этого в консоли просто возвращает длину объекта, который я передаю ему, а не true или false, что заставило меня задуматься над целями синтаксиса. Это какой-то высокоуровневый метод ниндзя JavaScript, о котором я не знаю? Если да, пожалуйста, просветите меня!

Ответы

Ответ 1

Источник: ССЫЛКА

Это правый сдвиг нулевой заливки оператор, который сдвигает двоичный представление первого операнда право на количество мест указанный вторым операндом. Биты смещены вправо, отбрасываются и нули добавляются слева. С положительным числом вы получите тот же результат, что и при знак-сдвигающий оператор сдвига, но отрицательные числа теряют свой знак становится позитивным, как в следующем пример, который (при условии, что 'a' будет -13) вернет 1073741820:

Код:

result = a >>> b;

Ответ 2

Двоичный оператор >>> (правый сдвиг) просто сдвигает самые правые биты числа определенное количество раз и заполняет нулями слева.

Примечание. В следующих примерах число в фигурных скобках после числа сигнализирует о том, в какой базе оно находится. 2 для двоичного кода, 10 для десятичного числа.

Например, 4 >>> 1 будет делать:

4(10) = 100(2)

4(10) >>> 1(10) = 010(2) = 2(10)
        shift once to the right

Другие примеры:

4(10) >>> 2(10) = 100(2) >>> 2(10) = 001(2) = 1(10)

10(10) >>> 4(10) = 1010(2) >>> 4(10) = 0000(2) = 0(10)

15(10) >>> 1(10) = 1111(2) >>> 1(10) = 0111(2) = 7

Как я помню, это нужно переместить необходимое количество бит вправо, а затем записать номер. Например, в последнем примере я просто переместил все вправо один раз, поэтому результат равен 0111.

Смещение 0 раз делает... ничего. Не знаю, почему это там.

Ответ 3

>>> является оператором Zero-fill right shift. Как уже установлено:

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

Также упоминается здесь, что:

Побитовые операторы обрабатывают свои операнды как последовательность из 32 бит (нули и единицы), а не как десятичные, шестнадцатеричные или восьмеричные числа. [...] Побитовые операторы выполняют свои операции над такими двоичными представления, но они возвращают стандартные числовые значения JavaScript.

Вместе эти утверждения утверждают, что expr >>> 0 всегда будет возвращать положительное число следующим образом:

  • expr передается в 32-разрядное целое число для побитовой операции
  • >>> 0 не действует (никакие биты не сдвинуты)
  • Результат преобразуется в Number

Вот несколько выражений и их результат:

        1 >>> 0 // 1 -- Number cast to 32-bit integer then back to Number
      "1" >>> 0 // 1 -- String cast to 32-bit integer then back to Number
undefined >>> 0 // 0 -- failed cast yields zero

Другие интересные случаи:

      1.1 >>> 0 // 1          -- decimal portion gets it
       -1 >>> 0 // 4294967295 -- -1 = 0xFFFFFFFF
                //               Number(0xFFFFFFFF) = 4294967295
      "A" >>> 0 // 0          -- cast failed
    "1e2" >>> 0 // 100        -- 1x10^2 is 100
   "1e10" >>> 0 // 1410065408 -- 1x10^10 is 10000000000
                //               10000000000 is 0x00000002540BE400
                //               32 bits of that number is 0x540BE400
                //               Number(0x540BE400) is 1410065408

Примечание: вы заметите, что ни один из них не возвращает NaN.