繁体   English   中英

解释这个 javascript 函数是如何工作的(在 Douglas Crockford 'How Javascript Works' 中找到)

[英]explain how this javascript function works (found in Douglas Crockford 'How Javascript Works')

我想了解make_binary_op()函数是如何工作的。 它需要两个不同的参数

  1. 函数参数addopmulop
  2. 一个数组参数( 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);

代码按规定工作。 answer38my_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需要是一个函数,可以mulopmul作用上述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的类(构造函数)来做到这一点,这样除了pushpop之外,它还可以支持addmul

 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.

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