Смущен полифиллом Array.prototype.reduce

Этот код является полифилом Array.prototype.reduce, предоставленным в сети разработчиков Mozilla. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function(callback /*, thisArg*/) {
    var T, A, k
    if (this == null) {
      throw new TypeError('this is null or not defined')
    }

    var O = Object(this)
    var len = O.length >>> 0

    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function')
    }

    if (arguments.length > 1) {
      T = arguments[1]
    }

    A = new Array(len)
    k = 0

    while (k < len) {
      var kValue, mappedValue

      if (k in O) {
        kValue = O[k]
        mappedValue = callback.call(T, kValue, k, O)
        A[k] = mappedValue
      }
      k++
    }

    return A
  }
}

Чего я не понимаю, так это этих двух строк

1. Почему бы просто не использовать this?

var O = Object(this)

2.Возможно ли this быть null, зачем нужен этот код ниже?

if (this == null) {
  throw new TypeError('this is null or not defined')
}

3.Зачем нам нужен k in O? в то время как k < len, k всегда в O, это бесполезное состояние?

if (k in O) {
    kValue = O[k]
    mappedValue = callback.call(T, kValue, k, O)
    A[k] = mappedValue
  }

person Vic    schedule 09.07.2018    source источник
comment
Я собираюсь прокомментировать это, так как я не уверен на 100%. 1: var O заключает this в object. 2: this может быть нулевым, так как вы можете ввести значение null. 3: Objects created from built–in constructors like Array and Object have inherited non–enumerable properties from Object.prototype взято с сайта for...in statement   -  person Alex    schedule 09.07.2018
comment
Кто-нибудь еще, подробнее, спасибо   -  person Alex    schedule 09.07.2018
comment
@Alex k in O не имеет ничего общего с for … in   -  person Bergi    schedule 09.07.2018
comment
@Bergi прочитал первое предложение моего комментария.   -  person Alex    schedule 09.07.2018
comment
Просто любопытно, почему ваш заголовок спрашивает о reduce, но в теле вашего вопроса показан полифилл для map?   -  person Bergi    schedule 09.07.2018
comment
в то время как k < len, k всегда в O - нет, не в разреженных массивах (или любой другой объект O, который имеет length без всех свойств индекса)   -  person Bergi    schedule 09.07.2018


Ответы (1)


1. Почему бы просто не использовать это?

var O = Object(this)

В редакции 3 неопределенный или нулевой thisArg заменяется глобальным объектом, а ToObject применяется ко всем другим значениям, и этот результат передается как значение this.

Поэтому я предполагаю, что причина, по которой это делается, заключается в том, чтобы сохранить последовательность.

2. Возможно ли, что это значение null, зачем нужен этот код ниже?

if (this == null) {
  throw new TypeError('this is null or not defined')
}

Да, это может быть нулевым.

Выполните следующий код со строгим режимом и без него. Вы заметите, что в строгом режиме вывод нулевой, а в другом случае это окно.

// "use strict";
var x = function(){
    console.log(this);
    return this;
}

x.call(null);

3. Зачем нам нужно k в O? в то время как k ‹ len, k всегда в O, это бесполезное условие?

if (k in O) {
    kValue = O[k]
    mappedValue = callback.call(T, kValue, k, O)
    A[k] = mappedValue
  }

Не бесполезное условие, потому что оно проверяет, существует ли свойство. (см. в примерах операторов)

Добавление примера с разреженными массивами:

var a = new Array(3);
console.log(a); // [ , , ]
console.log(a.length); // 3
console.log(a[0]); // undefined
person Sotiris Kiritsis    schedule 09.07.2018
comment
Нет, in не проверяет перечислимость. Проверяет существование. - person Bergi; 09.07.2018
comment
@Sotiris Kiritsis О 3. Я думал, что пока k < len, тогда k всегда в O, поэтому k должно существовать в O - person Vic; 10.07.2018
comment
Обновлен пункт 3, с дополнительным примером. См. также комментарий @Bergi выше. - person Sotiris Kiritsis; 10.07.2018