简体   繁体   中英

Passing an anonymous function as a parameter with preset parameter values

I ran into this by accident and am not sure how my 'popAndGo' function is working.

function Calculator(){
  var stack = [];

  var popAndGo = function(performer){
    var firstPop = stack.pop();
    var secondPop = stack.pop();
    var result = performer(firstPop, secondPop);
    stack.push(result);
  };

  this.push = function(num){
    stack.push(num);
  };
  this.value = function(){
    return stack[stack.length -1];
  };
  this.plus = function(){
    popAndGo(function(first, second){
      return first + second;
    });
  };
 }

I was practicing making my code follow DRY practices, and created this popAndGo function. It takes an anonymous function and calls this function after it collects two parameters (check out the plus function).

I am not sure how these parameters are working. I understand parameters in general, they are basically placeholders for actual arguments you eventually pass the function.

But in the case of this.plus I am passing an anonymous function with two parameters. How are they then taking place taking place of performer(firstPop, secondPop)? I visualize it working something like this:

  var popAndGo = function(performer){
    var firstPop = stack.pop();
    var secondPop = stack.pop();
    var result = performer(firstPop, secondPop);
    stack.push(result);
  };

  this.plus = function(){
    popAndGo(function(first, second){
      return first + second;
    });
  };
 }

 // CHECK the parameters on this popAndGo, this is how I picture this working.

 var popAndGo = function(function(first, second){ 
    var firstPop = stack.pop();
    var secondPop = stack.pop();
    var result = function(first, second);
    stack.push(result);
  };

These values do not match. If anyone can explain how this function is being passed into my popAndGo function and being matched to the values it would clear up a lot of confusion I am having, thanks!

Test Cases I am writing this code for:

// See http://en.wikipedia.org/wiki/Reverse_Polish_notation
describe("Calculator using reverse polish notation", function() {
  var calculator;

  beforeEach(function(){ 
    calculator = new Calculator();
  });

  it("adds two numbers", function() {
    calculator.push(2);
    calculator.push(3);
    calculator.plus();
    expect(calculator.value()).toEqual(5);
  });

  it("adds three numbers", function() {
    calculator.push(2);
    calculator.push(3);
    calculator.push(4);
    calculator.plus();
    expect(calculator.value()).toEqual(7);
    calculator.plus();
    expect(calculator.value()).toEqual(9);
  });
}

There are more tests and more functions I had to write for it. In every function I was popping 2 values from the stack then pushing the total back on. I wanted to write a function where I did this so I wasn't constantly repeating myself.

this.plus = function(){
    popAndGo(function(first, second){ 
      return first + second;
    });
};

The function that you pass as the argument to popAndGo is an anonymous function with two parameters. That anonymous function gets bound to the parameter performer in popAndGo .

When calling performer with the values of firstPop and secondPop these get bound to the parameters first and second in the anonymous function. The anonymous function's body gets executed returning the sum of the arguments.

Maybe you will visualize it better this way:

var popAndGo = function(){
    var performer = function(first, second){
        return first + second;
    };
    var firstPop = stack.pop();
    var secondPop = stack.pop();
    var result = performer(firstPop, secondPop);
    stack.push(result);
};

Or, simplifying,

var popAndGo = function(){
    var firstPop = stack.pop();
    var secondPop = stack.pop();
    var result = firstPop + secondPop;
    stack.push(result);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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