最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

functional programming - JavaScript: Anonymous vs Helper function - Stack Overflow

programmeradmin2浏览0评论

I'm trying to understand this functional style code from the book Eloquent Javascript:

.html#exercise1

When the count() function passes an anonymous function to reduce() the code works. But if I break the function out into a helper function then I get a reference error.

Can anyone explain why count() works but countHelper() does not?

var numbers = [1,2,3,0,1,2,3,0]

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

function reduce(bine, base, array) {
  forEach(array, function (element) {
    base = bine(base, element);
  });
  return base;
}

function equals(x) {
  return function(element) { return x === element;};
}

function count(test, array) {  
  return reduce(function(base, element) {
    return base + (test(element)?1:0);
  }, 0, array);
}

function countHelper(test, array) {
  function helper(base, element) {
    return base + (test(element)?1:0);
  }
  return reduce(helper(base, element), 0, array);
}

function countZeroes(array) {
  return count(equals(0), array);
}

print(countZeroes(numbers)) // 2

function countZeroesHelper(array) {
  return countHelper(equals(0), array);
}

print(countZeroesHelper(numbers)) // ReferenceError: base is not defined

I'm trying to understand this functional style code from the book Eloquent Javascript:

http://eloquentjavascript/chapter6.html#exercise1

When the count() function passes an anonymous function to reduce() the code works. But if I break the function out into a helper function then I get a reference error.

Can anyone explain why count() works but countHelper() does not?

var numbers = [1,2,3,0,1,2,3,0]

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

function reduce(bine, base, array) {
  forEach(array, function (element) {
    base = bine(base, element);
  });
  return base;
}

function equals(x) {
  return function(element) { return x === element;};
}

function count(test, array) {  
  return reduce(function(base, element) {
    return base + (test(element)?1:0);
  }, 0, array);
}

function countHelper(test, array) {
  function helper(base, element) {
    return base + (test(element)?1:0);
  }
  return reduce(helper(base, element), 0, array);
}

function countZeroes(array) {
  return count(equals(0), array);
}

print(countZeroes(numbers)) // 2

function countZeroesHelper(array) {
  return countHelper(equals(0), array);
}

print(countZeroesHelper(numbers)) // ReferenceError: base is not defined
Share Improve this question asked Feb 15, 2013 at 1:17 NTUINTUI 3394 silver badges12 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

In countHelper(), you are actually calling the helper function immediately when you pass arguments to reduce() and passing its return value to reduce (which isn't what you want), rather than passing a reference to the function so reduce() can call the function when it wants to. You have this:

function countHelper(test, array) {
  function helper(base, element) {
    return base + (test(element)?1:0);
  }
  return reduce(helper(base, element), 0, array);
}

It should be this:

function countHelper(test, array) {
  function helper(base, element) {
    return base + (test(element)?1:0);
  }
  return reduce(helper, 0, array);
}

Note the difference in arguments to the reduce() function.

When you want to pass a function as an argument, you don't include the parens after it because that just causes it to be executed right away and passes the return value from executing it rather than just passing a reference to the function itself.

This is a mon mistake in an untyped language like Javascript that lets you pass anything in any argument. Even seasoned programmers occasionally make this mistake (myself included). The important distinction to understand is the difference between executing the function vs. passing a reference to the function.

发布评论

评论列表(0)

  1. 暂无评论