[英]explain how this javascript function works (found in Douglas Crockford 'How Javascript Works')
我想了解make_binary_op()
函数是如何工作的。 它需要两个不同的参数
addop
或mulop
my_little_stack
/ my_little_array
) 我已经使用 firefox 调试器来观察执行,但仍然不明白make_binary_op()
函数是如何工作的。 我得到了所有的流行音乐和推动等。
function make_binary_op(func) { return function(my_little_array) { let wunth = my_little_array.pop(); let zeroth = my_little_array.pop(); my_little_array.push(func(zeroth, wunth)); return my_little_array; }; }; let addop = make_binary_op(function(zeroth, wunth) { return zeroth + wunth; }); let mulop = make_binary_op(function(zeroth, wunth) { return zeroth * wunth; }); let my_little_stack = []; my_little_stack.push(3); my_little_stack.push(5); my_little_stack.push(7); mulop(my_little_stack); // my_little_stack is [3, 35] addop(my_little_stack); // my_little_stack is [38] let answer = my_little_stack.pop(); // my_little_stack is [] console.log(answer);
代码按规定工作。 值answer
是38
, my_little_stack
是[]
。
首先看看算法的这个更简单的变体可能会有所帮助,其中没有函数返回函数这样的魔法:
function binary_op(func, my_little_array) { // Two arguments let wunth = my_little_array.pop(); let zeroth = my_little_array.pop(); my_little_array.push(func(zeroth, wunth)); return my_little_array; }; let add = function(zeroth, wunth) { // No call to make_binary_op return zeroth + wunth; }; let mul = function(zeroth, wunth) { return zeroth * wunth; }; let my_little_stack = []; my_little_stack.push(3); my_little_stack.push(5); my_little_stack.push(7); binary_op(mul, my_little_stack); // we need to pass two arguments binary_op(add, my_little_stack); let answer = my_little_stack.pop(); console.log(answer);
我想您将能够理解这是如何工作的:新的binary_op
函数采用回调函数(对两个参数执行操作)和堆栈。 然后它从堆栈中弹出两个值,将它们传递给回调函数,从中获取结果,并将该结果(可能是总和或乘积)压入堆栈。 因此堆栈的大小减少了 1:两个操作数被func
对它们的结果替换。
假设您遵循它的工作原理,现在看看我们如何做到这一点而不是这样:
binary_op(mul, my_little_stack);
...我们可以这样写:
mulop(my_litte_stack);
mulop
需要是一个函数,可以mulop
将mul
作用和上述binary_op
作用结合起来。
这就是函数make_binary_op
用武之地:它创建(并返回)一个专门为您想到的运算符(并且作为参数传递)量身定制的函数。 如果您将mul
传递给make_binary_op
,它将生成一个实现上述binary_op
函数的函数,专门为mul
量身定制:当该创建的函数被调用时,它将调用mul。 但请注意,动态创建的函数如何只需要一个参数(堆栈),因为它已经知道另一个参数 ( func
)。 它存在于返回该函数的“闭包”中。
对这种模式的一种批评可能是以下观察:虽然使用点符号 ( my_little_array.push
) 将项目添加到my_little_array
,但操作 mul/add 必须表达为函数调用,其中my_little_array
作为参数传递。 为什么不能让它也与点符号一起使用,以便您可以编写my_little_array.mul()
?
在 JS 语言的当前状态下,您可以使用扩展Array
的类(构造函数)来做到这一点,这样除了push
和pop
之外,它还可以支持add
和mul
:
class PolishCalc extends Array { static registerBinaryOp(func) { this.prototype[func.name] = function () { let wunth = this.pop(); let zeroth = this.pop(); this.push(func(zeroth, wunth)); return this; } } } // Extend the prototype with add and mul methods: PolishCalc.registerBinaryOp(function add(zeroth, wunth) { return zeroth + wunth; }); PolishCalc.registerBinaryOp(function mul(zeroth, wunth) { return zeroth * wunth; }); let polishCalc = new PolishCalc; polishCalc.push(3, 5, 7); let answer = polishCalc.mul().add().pop(); // the method calls can be chained... console.log(answer);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.