2014-04-13 184 views
0

我偶然遇到了这个问题,不确定我的'popAndGo'函数是如何工作的。将匿名函数作为参数传递给预设的参数值

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; 
    }); 
    }; 
} 

我正在练习让我的代码遵循DRY实践,并创建了这个popAndGo函数。它采用一个匿名函数,并在收集两个参数(检查加号函数)后调用该函数。

我不确定这些参数是如何工作的。我通常理解参数,它们基本上是您最终通过函数的实际参数的占位符。

但是在this.plus的情况下,我传递了一个具有两个参数的匿名函数。他们如何代替表演者(firstPop,secondPop)?我想象它的工作原理如下:

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); 
    }; 

这些值不匹配。如果任何人都可以解释如何将这个函数传入我的popAndGo函数并且与这些值相匹配,那么它会清除我所遇到的很多混乱,谢谢!

测试用例我写这个代码:

// 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); 
    }); 
} 

有更多的测试和更多的功能,我不得不为它编写。在每一个函数中,我都从堆栈中弹出两个值,然后再推回总值。我想写一个功能,我这样做,所以我没有不断重复自己。

+0

你能告诉我们你想怎么用'Calculator'的实例进行交互? – naomik

+0

当然,让我发布我正在编写的代码传递的测试。 – HelloWorld

+1

我不明白你在问什么,但是如果你想知道'first'和'second'从哪里得到它们的值,那是因为你正在向函数传递值:'performer(firstPop,secondPop)'。 –

回答

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

您作为参数传递给popAndGo的函数是具有两个参数的匿名函数。该匿名函数绑定到popAndGo中的参数performer

当调用performerfirstPopsecondPop这些值获取绑定的参数在匿名函数firstsecond。匿名函数的主体得到执行返回参数的总和。

+0

“匿名”部分是无关紧要的,考虑“* popAndGo *传递一个带有两个参数的函数......”从* popAndGo *的角度来看,函数是使用未命名的函数表达式创建的,而不是命名的函数声明没有区别。 – RobG

+0

@RobG当然,我试图尽可能明确地解释发生了什么,使用“匿名”可以更容易地指出我指的是哪个函数。 –

3

,我可能会写这样

function Calculator(initialNum) { 

    var result = 0; 

    // private api 
    function set(num) { 
    return result = num || 0; 
    } 

    function add(num) { 
    return set(result + num); 
    } 

    function subtract(num) { 
    return set(result - num); 
    } 

    function divide(num) { 
    if (num === 0) throw new Error("Cannot divide by zero"); 
    return set(result/num); 
    } 

    function multiply(num) { 
    return set(result * num); 
    } 

    function value() { 
    return result; 
    } 

    function clear() { 
    return set(0); 
    } 

    // exports; public api 
    this.add  = add; 
    this.subtract = subtract; 
    this.divide = divide; 
    this.multiply = multiply; 
    this.value = value; 
    this.clear = clear; 

    // "magic" api 
    this.valueOf = value; 

    // init 
    set(initialNum); 
} 

使用

var a = new Calculator; // 0 
a.add(5);    // 5 
a.add(10);    // 15 
a.divide(5);   // 3 
a.multiply(3);   // 9 

计算器可以相互合作过

var b = new Calculator(3); // 3 
b.add(3);    // 6 
b.multiply(a);   // 54 
b.clear();    // 0 
+a;      // 9 
+1

这并不回答OP的问题,并且使得计算器不那么强大:现在它不能用于计算(1 + 2)*(3 + 4)。 – tom

2

也许你会更好地显现这样说:

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); 
}; 

或者简化,

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

Oriol,我认为关键是HelloWorld不希望在'popA​​ndGo'中静态定义计算器操作;你的设置为'+'。例如,如何定义'/'和'-'和'*'? – naomik

+0

@naomik我并不是说应该用我的代码替换代码,我只是用'function(first,second){return first + second;')来调用'popA​​ndGo'。 }' – Oriol

相关问题