【问题标题】:explain how this javascript function works (found in Douglas Crockford 'How Javascript Works')解释这个 javascript 函数是如何工作的(在 Douglas Crockford 'How Javascript Works' 中找到)
【发布时间】:2019-09-16 23:07:05
【问题描述】:

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

代码按规定工作。 answer 的值是 38my_little_stack 最后是 []

【问题讨论】:

  • 这个问题属于codereview.stackexchange.com
  • 你能说得更具体点吗?您需要帮助的具体部分是什么?
  • @JorgeFuentesGonzález 不,它没有。 OP 不是要求就如何改进它提供反馈,而是要求了解它是如何工作的。
  • 请教时不能有一个正确答案。
  • 你只需要了解高阶函数。 make_binary_op 只接受一个参数,并返回一个函数。它返回的函数是分配给addopmulop 的函数。

标签: javascript function stack binary-operators


【解决方案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.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);

【讨论】:

    猜你喜欢
    • 2015-02-20
    • 2015-01-31
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多