Почему эта функция с «этим» не работает?Об «этом» и его сфере применения - PullRequest
0 голосов
/ 19 февраля 2019

Я знаю, что добавление метода к прототипу не является лучшим, но я просто тестирую.

Array.prototype.maap = function (transform) {
  let mapped = [];
  for (let element of this) {
        mapped.push(transform(element));
  }
  return mapped;
}

console.log([0, 2, 3].maap(n => n / this.length));

Я получаю:

[NaN, Infinity, Infinity].Я думаю, что проблема заключается в "this.length".

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

this внутри функции стрелки ссылается на тот же this в содержащем его блоке.Здесь содержащий блок является верхним уровнем, где this относится к window, а window.length равно 0.

console.log(this === window);
console.log(window.length);

Итак, ваш код эквивалентен:

Array.prototype.maap = function(transform) {
  let mapped = [];
  for (let element of this) {
    mapped.push(transform(element));
  }
  return mapped;
}

console.log(this.length);
console.log([0, 2, 3].maap(n => n / 0));

0 / 0 равен undefined, а большинство других чисел / 0 равно Infinity (или -Infinity).

Если выЕсли вы хотите эмулировать поведение Array.prototype.map с помощью this, второй аргумент, передаваемый maap, должен иметь значение this, с которым вызывается обратный вызов:

Array.prototype.maap = function(transform, thisVal) {
  let mapped = [];
  for (let element of this) {
    mapped.push(transform.call(thisVal, element));
  }
  return mapped;
}

const arr = [0, 2, 3];
console.log(arr.maap(
  function(n){ return n / this.length; },
  arr
));
0 голосов
/ 19 февраля 2019

Я думаю, что проблема в функции стрелки (параметр transform), Да, this.length - это вопросы, связанные напрямую, углубляйтесь, это проблема в функции стрелки ,

Функция стрелки не имеет своей собственной this.Используется значение this лексической области видимости;

Проще говоря, function, где указана функция стрелки, где точка this.

Итак, для вашего кодапереданные вами параметры - n => n / this.length, и он определен в функции console.log в среде window.Итак, настоящая проблема:

transf = (n) => {
  console.log(this);    // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
  return n / this.length
}
console.log([0, 2, 3].maap(transf));
0 голосов
/ 19 февраля 2019

Вы правы, проблема this.length.Беда в том, что он не в функции !Он находится в лямбда-выражении, область которого не совпадает с областью массива, к которой он позже вызывается.Таким образом, this - это не массив, а this.length - это сплошной 0 (0/0 - NaN, 2/0 - бесконечность, а 3/0 - бесконечность).

Вы можете использовать жесткий кодреальное значение 3, или переместите свою логику в саму функцию.Либо лямбда (на самом деле «функция стрелки» в JavaScript) может принимать другой параметр: знаменатель.

Array.prototype.maap = function (transform) {
  let mapped = [];
  for (let element of this) {
        mapped.push(transform(element, this.length));
  }
  return mapped;
}

console.log([0, 2, 3].maap((n, m) => n / m));
...