为什么带有“ this”的此功能不起作用?关于“此”及其范围

时间:2019-02-19 01:24:25

标签: javascript scope this

我知道用这种方法向原型添加方法并不是最好的方法,但我只是在测试。

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,无穷大,无穷大]。我认为问题是“ this.length”。

3 个答案:

答案 0 :(得分:3)

是的,问题是this.length。麻烦的是它不在函数中!它在lambda中,其作用域不是后来被其调用的数组的作用域。因此,this不是数组,this.length是实数0(0/0为NaN,2/0为无穷大,而3/0也为无穷大)。

您可以对实际值3进行硬编码,也可以将逻辑移入函数本身。或者,您可以让lambda(实际上是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));

答案 1 :(得分:1)

箭头函数内的

this在其包含块中引用相同的this。这里,包含块是顶层,其中thiswindow,而window.length0

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 / 0undefined,而其他大多数数字/ 0Infinity(或-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
));

答案 2 :(得分:1)

我认为问题出在箭头函数(参数transform)上,是的,this.length是直接相关的问题,更深入地讲,这是关于arrow function的问题,

  

箭头功能没有自己的this。使用了封闭词法范围的this值;

简单地放置,箭头功能定义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));