【问题标题】:Making my own ForEach() javascript - element is not defined制作我自己的 ForEach() javascript - 未定义元素
【发布时间】:2018-09-25 15:26:31
【问题描述】:

我正在用 JavaScript 自己实现 forEach,唯一的目的是更好地理解语言。更具体地说,临时目标是更好地理解回调。

这就是我在卡住之前走了多远。

function myForEach(array, callback) {
  for (let i = 0; i < this.length; i++) {
    callback(array[i]);
  }
}

function callback(element) {
  console.log(element); //insert logic
}

const array = [2, 4, 6, 8, 10];
arr.myForEach(array, callback(element));

在节点中运行时出现以下错误:

ReferenceError: element is not defined
    at Object.<anonymous> (C:\Users\Jonas\Desktop\FLEXBOX\test.js:54:31)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

我怀疑是因为在调用函数时,回调函数中作为参数给出的元素没有被创建。这是有道理的,但真正的 forEach 循环在被调用时并没有传入尚未创建的值?

arr.forEach((element /*does not exist yet?*/) => {
    console.log(element);
});

我也尝试使用 lambda 调用该方法,但也没有得到正确的结果。但是一个不同的错误

arr.myForEach(array, (element) => {
    console.log(element);
});

然后它给出错误:

TypeError: arr.myForEach is not a function
    at Object.<anonymous> (C:\Users\Jonas\Desktop\FLEXBOX\test.js:58:5)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

【问题讨论】:

  • 你引用的错误不是代码抛出的错误。你应该提供一个真实的minimal reproducible example
  • “我也尝试使用 lambda 调用该方法,但没有解决任何问题。” 这不正确,它解决了一个问题,但您的代码仍然包含一些错误/错误。
  • 您的代码还有其他问题(现在没有时间输入完整答案),但最直接的问题是 element 仅在 callback 中定义。相反,您应该将 callback 作为函数引用传递。

标签: javascript foreach


【解决方案1】:

这就是你实现它的方法

    Array.prototype.myForEach = function(callback) {
      for (let i = 0; i < this.length; i++) {
        callback(this[i]);
      }
    };
    
    function callback(element) {
      console.log(element); //insert logic
    }
    
    var array = [2, 4, 6, 8, 10];
    array.myForEach( callback);

错误 element not defined is because in last line you use 'callback(element)' ,在该行元素未定义

并且为了能够在 array.myForEach 这样的数组上调用方法,您必须将它附加到原型

注意:不建议更改内置原型。感谢 cmets 伙计们

【讨论】:

  • 我构建了相同的代码,但有一点需要注意——因为您已将其直接附加到 Array 原型,所以您拥有引用的伪变量 this。这意味着您可以(并且应该)在最后一行将数组作为其自身的参数删除,并在第一行将其作为必需参数删除。
  • 由于您使用的是Array.prototype,您可能希望删除对array 的引用并仅使用this
  • 这是迄今为止我最喜欢的答案!我喜欢用这个。另外,因为它使它更通用。我会尽可能标记为答案:)
  • @JonasGrønbek 请注意,修改原生 JavaScript 元素的原型可能存在风险,通常被认为是在生产代码中避免的一种做法。 (这也是我们不能拥有 Array.flatten 的原因......感谢 mootools ...)
【解决方案2】:

你有几个错误,检查一下:

function myForEach(array, callback) {
    for (let i = 0; i < array.length; i++) { 
        callback(array[i]);
    }
}

function callback(element) {
    console.log(element); //insert logic
}

const array = [2, 4, 6, 8, 10];
myForEach(array, callback); 

错误是(见 cmets):

function myForEach(array, callback) {
  for (let i = 0; i < this.length; i++) { // what is this? You need array.length
    callback(array[i]);
  }
}

function callback(element) {
  console.log(element); //insert logic
}

const array = [2, 4, 6, 8, 10];
arr.myForEach(array, callback(element)); 
// arr.myForEach is not possible, because myForEach is not a method of JS arrays 
// callback(element) this invokes a function, you just need to pass it like callback (without parentheses)

【讨论】:

    【解决方案3】:

    元素未定义

    你得到这个是因为element 在遇到这一行时没有定义:

    arr.myForEach(array, callback(element));`
    

    该代码表示​​立即调用callback,传入一个名为element(不存在)的变量,然后将回调的结果传递给myForEach

    arr.myForEach 不是函数

    你得到这个是因为你没有修改 Array.prototype 来拥有一个 myForEach 函数,所以 arr.myForEach 是未定义的。您编写 myForEach 的方式应该像这样调用它:

    myForEach(array, (element) => console.log(element))
    

    myForEach(array, callback);
    

    【讨论】:

    • 这表明出了什么问题,但它并不指向我解决我的问题。感谢您的回答,但我不会将其标记为一个,因为它不是:)
    【解决方案4】:
    const arr = [2, 4, 6, 8, 10];
    myForEach(arr, callback); 
    

    您编写的函数应该以上述方式调用。

    【讨论】:

      【解决方案5】:

      有几种方法可以解决这个问题。我认为你试图去修改数组本身以拥有你的功能,在这种情况下,下面的代码就是这样做的。请注意,我将函数分配为数组的 instance 的属性。您也可以修改Array.prototype ... 但这通常被认为是一个危险且不明智的想法。 (旁注,在您的代码中,您没有将回调传递给函数,而是调用callback(element) 并将结果(未定义)传递给函数。

      function myForEach(callback) {
          for (let i = 0; i < this.length; i++) {
              callback(this[i]);
          }
      }
      
      function callback(element) {
          console.log(element); //insert logic
      }
      
      const arr = [2, 4, 6, 8, 10];
      arr.myForEach = myForEach;
      arr.myForEach(callback);

      您可以这样做的另一种方法是将数组和回调都传递给一个函数,在这种情况下您不想使用this

      function myForEach(array, callback) {
          for (let i = 0; i < array.length; i++) {
              callback(array[i]);
          }
      }
      
      function callback(element) {
          console.log(element); //insert logic
      }
      
      const array = [2, 4, 6, 8, 10];
      //myForEach(array, callback(element));
      myForEach(array, callback); 

      【讨论】:

      • 我已将您标记为答案,因为您指出了代码不起作用的原因,并给出了一个很好解释的解决方案。谢谢dgeare,一个非常愉快的答案!
      • @JonasGrønbek 很高兴我能帮上忙 ^_^b
      【解决方案6】:

      您收到此错误的原因是“元素”在此实例中没有引用任何内容。您需要遍历数组,然后将逻辑添加到每个元素,假设您想添加两个来教数组的元素,您的回调函数可能如下所示:

      function specificAFunction( arr ) {
      let arrayResult = [];
      arr.forEach( element => arrayResult.push(element + 2) );
      return arrayResult;
      };
      

      然后您可以使用函数和值数组调用您的第一个函数:

      const values = myFilter(myArray, specificAFunction);
      

      【讨论】:

        【解决方案7】:

        在这里你可以创建你自己调用的打印函数接受一个条件函数

        var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        
        Array.prototype.arrayPrint = function (calback)
        {
            for (let index = 0; index < this.length; index++) {
                if (calback(this[index], index))
                {
                    console.log(this[index]);                
                }
            }
        }
        
        function ifOdd(elem, index)
        {
            return elem % 2 == 0;    
        }
        
        array.arrayPrint(ifOdd);
        

        【讨论】:

          猜你喜欢
          • 2017-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多