学生试图理解回调函数

3

你好,我正在尝试学习如何实现回调函数。我的老师已经帮助我多次,但我仍然无法通过以下方程传递数据。我试图获取数组的某些元素,并将它们推送到一个新的函数中,只有它们在函数中通过了测试才能推送。请看一下,并感谢您的意见。欢迎您进一步提供资源以帮助我更好地理解。

// EACH DEFINITION
function each (collection, callback) {
    for(var i = 0; i < collection.length; i ++){
    callback(collection[i]);
  }
}


// VARIABLE DECLARATION
var myArray = [1,2,3,4,5,6];
var isEven = function (num) {
  return num % 2 === 0;
};

// IMPLEMENT DEFINITION
function implement(array, test){ // array = myArray, test = isEven
  var arr = [];
  each(array, function(item){
    test(item);
  });
    if(test(array)){
      arr.push(array);

    }

  return arr;
}

// IMPLEMENT INVOCATION

implement(myArray, isEven);

你为什么要在循环外推出结果? - ShuberFu
5个回答

3
你正在each()循环外部创建arr
我认为你的代码应该像这样:
// IMPLEMENT DEFINITION
function implement(array, test){ // array = myArray, test = isEven
  var arr = [];
  each(array, function(item){
    if(test(item)) {
        arr.push(item);
    }
  });

  return arr;
}

虽然在这种情况下,你的implement()过滤函数没有任何必要,因为javascript数组原型已经有了一个filter方法。你可以简化你的调用如下:

var filteredArray = myArray.filter(isEven);

尽管您可能希望将您的isEven定义更改为更正确的形式:

var isEven = function (num, index, array) {

在你的情况下,你不需要使用最后两个参数。

2
有点唠叨,但我认为你的意思是 JavaScript 而不是 Java。 - ste2425
@ste2425 当然,我确实喜欢 :) - Mike Brant

0
两点:
首先,您的回调函数实现是正确的。就回调概念而言,您正在正确地调用和传递函数。
但是,您的 `implement()` 函数可能有一个 bug。您只有在 `each()` 已经被调用后才将其推入 `arr`:
function implement(array, test) { // array = myArray, test = isEven
    var arr = [];
    each(array, function(item) {
        result = test(item);
    });

    // This block should be in the loop itself
    // It should also refer to item, not array
    if (test(array)) {
        arr.push(array);
    }

    return arr;
}

根据您提供的代码,尝试使用此修复方法:

// EACH DEFINITION
function each(collection, callback) {
  for (var i = 0; i < collection.length; i++) {
    callback(collection[i]);
  }
}


// VARIABLE DECLARATION
var myArray = [1, 2, 3, 4, 5, 6];
var isEven = function(num) {
  return num % 2 === 0;
};

// IMPLEMENT DEFINITION
function implement(array, test) { // array = myArray, test = isEven
  var arr = [];
  each(array, function(item) {
    if (test(item)) {
      arr.push(item)
    }
  });
  
  if (test(array)) {
    arr.push(array);

  }

  return arr;
}

// IMPLEMENT INVOCATION

var result = implement(myArray, isEven);
console.log(result); // For snippet results


0

你定义的回调函数是

function(item){
  test(item);
}

这将仅对每个item调用test,就是这样。由于您想进一步添加itemarr,如果test返回true,则应该将检查代码放在回调函数中,使其变为

function(item){
  if (test(item)) {
    arr.push(item);
  }
}

这样该函数将会被调用每一个项目。

另外,这部分

if(test(array)){
  arr.push(array);
}

这是不正确的,因为您正在将整个数组传递到期望数字的isEven中。 test(array)将始终返回false; 这就是为什么您的arr为空的原因。

修改您的代码以按您想要的方式工作,应该是这样的

// IMPLEMENT DEFINITION
function implement(array, test){ // array = myArray, test = isEven
  var arr = [];
  each(array, function(item){
    if (test(item)) {
      arr.push(item);
    }
  });

  return arr;
}

就资源而言,回调函数的教程在网上广泛可得,还有最佳实践。你可以通过谷歌轻松找到最适合你的教程。


0

我觉得整个问题在于你指定的实现部分。所有其他代码看起来都足够好。

each(array, function(item){
   test(item);
});

好的,首先让我们检查一下这段代码。您正在调用每个函数,该函数将使用在此处定义的回调匿名函数,如所示。

但是,如果您查看每个函数本身,它没有返回值(这意味着默认情况下它返回未定义)。每个函数也没有进行任何修改。因此,这组代码对代码的执行没有影响,并且从某些高级编译技术来看,如果使用的是chrome中的V8引擎,则实际上可能被删除。

这意味着您的代码仅在执行方面起作用。

var arr = [];
if(test(array)){
  arr.push(array);

}
return arr;

目前,测试仍然是isEven函数,因此您基本上正在询问这个问题

if(array % 2 === 0) arr.push(array);

在JavaScript中,当数组用于条件语句时,它们的行为非常有趣。在这种情况下,数组本质上会调用toString方法(更深入的解释请参见:https://dev59.com/nmPVa4cB1Zd3GeqP8b2p#10556035,但基本上当你有一个对象 === 数字时,它将尝试在对象上使用toPrimitive方法,结果是一个字符串),这使得它变成了一个字符串。
if("1,2,3" % 2 === 0)

这是错误的。因此,arr 保持不变,并以其原始状态 [] 返回。


0
// EACH DEFINITION
function each (collection, callback, results) {
  for(var i = 0; i < collection.length; i ++){
    callback(collection[i]);
  }
  console.log(results);
}


// VARIABLE DECLARATION
var myArray = [1,2,3,4,5,6];
var isEven = function (num, array) {
  return num % 2 === 0;
};

// IMPLEMENT DEFINITION
function implement(array, test){ // array = myArray, test = isEven
  var arr = [];
  function filter (item) {
    if (test(item)) {
      arr.push(item);
    }
  }
  each(array, filter, arr);
  // If you return arr here, it will still be empty. You must pass it to functions it is being operated on.
}

// IMPLEMENT INVOCATION

implement(myArray, isEven);

你不仅试图在循环外部推送到 arr,而且在 arr 获得任何值之前就尝试返回它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接