解释此javascript函数如何工作(请参见Douglas Crockford的“ Javascript如何工作”)

时间:2019-04-27 20:08:47

标签: javascript function stack binary-operators

我想了解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);

代码按指定方式工作。末尾的值answer38,而my_little_stack[]

1 个答案:

答案 0 :(得分:1)

首先看一下算法的这种更简单的变体可能会有所帮助,在这种变体中,没有像返回函数的函数这样的魔术:

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必须是一个可以一次性组合mul以上binary_op所做的功能的函数。

函数make_binary_op进入的地方:它创建(并返回)专门定制的函数 给您所考虑的运算符(以及您作为参数传递给运算符)。如果将mul传递给make_binary_op,它将产生 实现上述binary_op函数的函数,专门为mul量身定制:调用该创建的函数时 它会调用 mul。 但是请注意,动态创建的函数如何只需要一个参数(堆栈),因为另一个参数(func) 已经知道了。它存在于返回该函数的“闭包”中。

附录

对此模式的一种批评可能是以下观察:当使用点符号(my_little_array)将项目添加到my_little_array.push时,必须像函数调用那样表达mul / add操作,其中{ {1}}作为参数传递。为什么不能也使它与点符号一起使用,以便您可以编写my_little_array

在JS语言的当前状态下,您可以使用扩展my_little_array.mul()的类(构造函数)来执行此操作,因此除Arraypush之外,它还可以支持{{1 }}和pop

add