簡體   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