2

This code is polyfill of Array.prototype.reduce given on Mozilla Developer Network. 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
  }
}

What I don't understand is these two lines

1.Why not just use this?

var O = Object(this)

2.Is it possible this be null, why need this code below?

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

3.Why we need k in O? while k < len, k always in O, is it useless condition?

if (k in O) {
    kValue = O[k]
    mappedValue = callback.call(T, kValue, k, O)
    A[k] = mappedValue
  }
JLRishe
  • 99,490
  • 19
  • 131
  • 169
Vic
  • 105
  • 1
  • 9
  • I am going to comment this since I'm not 100% sure. **1:** `var O` wraps `this` as an `object`. **2:** `this` can be null as you can your input as null. **3:** `Objects created from built–in constructors like Array and Object have inherited non–enumerable properties from Object.prototype` taken from [`for...in statement`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) – Alex Jul 09 '18 at 11:22
  • Someone else, elaborate more, thank you – Alex Jul 09 '18 at 11:23
  • @Alex `k in O` has nothing to do wit `for … in` – Bergi Jul 09 '18 at 12:55
  • @Bergi read the first sentence of my comment. – Alex Jul 09 '18 at 12:55
  • Just curious, why does your title ask about `reduce` but your question body shows the polyfill for `map`? – Bergi Jul 09 '18 at 12:55
  • "*while `k < len`, `k` always in `O`*" - no, not in [sparse arrays](https://stackoverflow.com/questions/1510778/are-javascript-arrays-sparse) (or any other object `O` that has a `length` without all the index properties) – Bergi Jul 09 '18 at 13:12

1 Answers1

2

1.Why not just use this?

var O = Object(this)

In Edition 3, an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.

So my guess is that the reasons this is being done is to keep consistency.

2.Is it possible this be null, why need this code below?

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

Yes, it is possible for this to be null.

Execute the following code with and without strict mode. You will notice that in strict mode the output is null, while in the other case its the window.

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

x.call(null);

3.Why we need k in O? while k < len, k always in O, is it useless condition?

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

Not a useless condition, because it checks if a property exists.(see in operator examples)

Adding an example with sparse arrays:

var a = new Array(3);
console.log(a); // [ , , ]
console.log(a.length); // 3
console.log(a[0]); // undefined
Sotiris Kiritsis
  • 3,178
  • 3
  • 23
  • 31