简体   繁体   English

如何在Array.map中获得正确的“this”?

[英]How do I get the right “this” in an Array.map?

I assume there is some application of call or apply here but I'm not sure how to implement it. 我认为有一些应用程序callapply在这里,但我不知道如何实现它。

http://codepen.io/anon/pen/oXmmzo http://codepen.io/anon/pen/oXmmzo

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    });
  }
}

a.showFooForEach();

Say I want to map an array, but in the function, I need access to the this to which foo belongs. 假设我想map一个数组,但在函数中,我需要访问foo所属的this The function of map creates a new this context, so I obviously need to coerse that context back in somehow, but how do I do that while still having access to thing ? mapfunction创建了一个新的this上下文,所以我显然需要以某种方式反驳那个上下文,但是如何在仍然可以访问thing时这样做呢?

Just realized I should have read the documentation for Array.map() more carefully. 刚刚意识到我应该更仔细地阅读Array.map()的文档。 One simply needs to pass in the this value as the second parameter of map() 一个人只需要传递this值作为map()的第二个参数

http://codepen.io/anon/pen/VLggpX http://codepen.io/anon/pen/VLggpX

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }, this);
  }
}
a.showFooForEach();

In addition, understanding how bind() , call() and apply() work are a must for serious JavaScript developers. 此外,理解bind()call()apply()工作对于认真的JavaScript开发人员来说是必须的。 These allow us to skip silly assignments like 这些允许我们跳过愚蠢的任务,如

var self = this;
myItems.map(function(item) {
  self.itemArray.push(item);
});

with

myItems.map(function(item) {
  this.itemArray.push(item);
}.bind(this));

As of 2018, you could use an arrow function: 自2018年起,您可以使用箭头功能:

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map((thing) => {
      console.log(this.foo, thing);
    });
  }
}

a.showFooForEach();

You could use bind() it to your context. 您可以将bind()用于您的上下文。

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }.bind(this));
  }
}

a.showFooForEach();

That's because of JS lexical scope 那是因为JS词汇范围

From MDN: 来自MDN:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。

Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 在这里阅读更多内容: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

And here: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/ 在这里: http//javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/

Also, map() does accept a second parameter as "this" 另外, map()确实接受第二个参数为“this”

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }, this);
  }
}

a.showFooForEach();

From MDN map() documentation: 来自MDN map()文档:

Parameters 参数

callback Function that produces an element of the new Array callback生成新数组元素的函数

thisArg Optional . thisArg 可选 Value to use as this when executing callback. 执行回调时要使用的值。

Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 进一步阅读: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Short advice 简短的建议

PS.: Array.map is usually called when you want to do something with your array, for example adding 10 to each item, or something like that... Since the Array.map returns a new array. PS。:当您想对数组执行某些操作时,通常会调用Array.map,例如为每个项添加10,或者类似的东西......因为Array.map返回一个新数组。 If you're only using console.log or something that wont affect the array itself you could just use a Array.forEach call instead 如果您只使用console.log或不会影响阵列本身的东西,您可以使用Array.forEach调用

Nothing complex needed! 没有什么复杂的需要! map takes a second param of thisArg , so you just pass it in with the function you want to invoke on each item: map需要thisArg的第二个参数,所以你只需要在每个项目上调用你想要调用的函数:

a = {
  foo: 'bar',
  things: [1, 2, 3],
  showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    }, this);
  }
}

a.showFooForEach();

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

There are three ways: 有三种方式:

An plain-old variable 一个普通的变量

One that doesn't have the special oddness of this : 一个不具有的特殊奇怪this

var self = this;
this.things.map(function(thing) {
  console.log(self.foo, thing);
});

Function.prototype.bind Function.prototype.bind

this.things.map(function(thing) {
  console.log(this.foo, thing);
}.bind(this));

Use the second parameter of Array.prototype.map 使用Array.prototype.map的第二个参数

The (optional) second parameter is the context that the inner function is called with. (可选)第二个参数是调用内部函数的上下文。

this.things.map(function(thing) {
  console.log(this.foo, thing);
}, this);

The first two ways are generic ways of dealing with this ; 前两种方式是处理this情况的通用方法; the third is specific to map , filter , forEach . 第三个特定于mapfilterforEach

map allows a second argument called "thisArg" so you just use that like so: map允许第二个名为“thisArg”的参数,所以你只需使用它:

showFooForEach: function() {
    this.things.map(function(thing) {
      console.log(this.foo, thing);
    },this);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM