json 如何将额外的参数传入JS Array.forEach()

vdzxcuhz  于 2023-08-08  发布在  其他
关注(0)|答案(5)|浏览(97)

只是想分享一个小技巧,我学会了传递变量到你的JS Array.forEach()方法的范围。
我遇到了一个需要使用forEach循环来构建数据集的情况。但是我还需要访问当前作用域中的变量(我需要能够在循环中引用this)。
这就是我当时的处境:

var dataset = {
    data: [],
    backgroundColor:[],
};

items.forEach(function (item) {

    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(this.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(this.yellow);
    } else {
        dataset.bgColor.push(this.red);
    }

}, this);

this.refreshGraph(dataset);

字符串
无法从循环内访问数据集。那么我们如何在迭代时访问它呢?
我还没有看到这个解决方案的堆栈溢出,它不适合任何问题,我可以找到。
答案如下:

ha5z0ras

ha5z0ras1#

如果你有一个函数超出了某些数据的范围,但需要访问它,你可以使用一个curried函数,它将该数据集作为第一个参数,并且仍然可以在整个过程中正常使用this

//curried function that uses `dataset` and `this` but it is not 
//in the context where the iteration happens 
function makeLoopCallback(dataset) {
  return function(item) {
    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(this.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(this.yellow);
    } else {
        dataset.bgColor.push(this.red);
    }
  }
}

//object to serve as `this` context for a function
var obj = {
  green: "Green",
  yellow: "Yellow",
  red: "Red",
  doSomething: function(items) {
    var data = {
        data: [],
        bgColor:[],
    };
  
    items.forEach(makeLoopCallback(data), this);
  
    return data;
  }
}

//set up some dummy data
var input = [ { age: 1 }, { age: 2 }, { age: 3 }, { age: 4 }, { age: 5 }, { age: 6 } ];

//call the function
console.log(obj.doSomething(input))

字符串
另一种方法是使用Array#reduce而不是Array#forEach,函数直接接受两个参数。由于.reduce无法设置this上下文,因此您可以使用Function#bind来执行此操作:

//external function that uses `dataset` and `this` but it is not 
//in the context where the iteration happens
function external(dataset, item) {
    dataset.data.push(item.age);

    if (item.age < 2) {
      dataset.bgColor.push(this.green);
    } else if (item.age < 5) {
      dataset.bgColor.push(this.yellow);
    } else {
      dataset.bgColor.push(this.red);
    }

    return dataset;
}

//object to serve as `this` context for a function
var obj = {
  green: "Green",
  yellow: "Yellow",
  red: "Red",
  doSomething: function(items) {
    var data = {
        data: [],
        bgColor:[],
    };

    return items.reduce(external.bind(this), data);
  }
}

//set up some dummy data
var input = [ { age: 1 }, { age: 2 }, { age: 3 }, { age: 4 }, { age: 5 }, { age: 6 } ];

//call the function
console.log(obj.doSomething(input))

ejk8hzay

ejk8hzay2#

使用es6的能力,如果你使用箭头函数,this将从

items.forEach(item => {
// You can use this as out of the forEach scope
});

字符串
From MDN Web Docs
箭头函数没有自己的this。使用封闭词法范围的this值;箭头函数遵循正常的变量查找规则。因此,当搜索当前作用域中不存在的this时,箭头函数最终会从其封闭作用域中找到this。
另一个很好的解释:https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

waxmsbnn

waxmsbnn3#

解决方案是传递一个JSON对象作为this参数。
所以之前我们有:

Array.forEach(function(){}, this) 
// "this" is just an object ^^^^ just like anything else in JavaScript

字符串
现在我们有:

Array.forEach(function(){}, {_self: this, dataset: dataset}) 

// you can access _self and dataset just as if they were in scope


现在你可以在使用匿名函数进行迭代时进行数据更改:)
完整示例:

var dataset = {
    data: [],
    backgroundColor:[],
};

items.forEach(function (item) {

    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(_self.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(_self.yellow);
    } else {
        dataset.bgColor.push(_self.red);
    }
}, { _self: this , dataset: dataset});

m528fe3b

m528fe3b4#

Array.prototype.forEach(callbackFun,?这个)
可以将dataset作为此参数传递给forEach

var dataset = {
data: [],
backgroundColor:[],
};

items.forEach(function (item) {

this.dataset.data.push(item.age);

if (item.age < 2) {
    this.dataset.bgColor.push(this.tempThis.green);
} else if (item.age < 5) {
    this.dataset.bgColor.push(this.tempThis.yellow);
} else {
    this.dataset.bgColor.push(this.tempThis.red);
}

}, {tempThis:this,dataset:dataset});

this.refreshGraph(dataset);

字符串

gijlo24d

gijlo24d5#

我找到了一个简单的

如果不需要上下文,可以简单地使用它来传递所需任何内容。

response.services.forEach(function(service) {

   //code

},undefined, <whatever i want to pass>);

字符串
我刚刚在第二个参数中传递了一个undefined,在第三个参数中我传递了额外的参数到JSArray.forEach()中
简短示例
[1,2,3].forEach(myCallback,undefined,'additionalFoo');
参考编号

相关问题