值區塊引數快取

有時候,區塊程式碼產生器需要多次參照其內部區塊的程式碼。

舉例來說,如果您有一個區塊取得清單的最後一個元素,就必須多次存取清單程式碼:

// Incorrect block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);

  // listCode gets referenced twice.
  const code = `${listCode}[${listCode}.length - 1]`;

  return [code, Order.MEMBER];
}

但如果內部區塊的程式碼產生的值不一致,或有副作用,則可能會造成問題。舉例來說,如果內部程式碼實際上是函式呼叫,這個特定程式碼最後可能會超出範圍條件:

randomList()[randomList().length - 1]

使用公用程式函式有助於確保內部區塊的程式碼只評估一次。

公用函式

公用程式函式是開發人員定義的函式,包含在產生的程式碼字串中。您可以使用這些程式碼,確保內部區塊程式碼只會「評估」一次,然後就能多次參照該值。

import {javascriptGenerator, Order} from 'blockly/javascript';

// Correct block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.NONE);
  const functionName = generator.provideFunction_(
      'list_lastElement',
      [
        `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`,
        `  return list[list.length - 1];`,
        `}`
      ]
  );

  // listCode only gets evaluated once.
  const code = `${functionName}(${listCode})`;
  return [code, Order.FUNCTION_CALL];
}

提供函式

您可以使用 provideFunction_ 定義區塊程式碼產生器中的公用程式函式。該函式採用您想要的公用程式函式名稱,以及定義函式用途的程式碼字串陣列。此方法會在修改公用程式函式之後 (可能) 傳回結果名稱,以免與使用者定義的函式衝突。

provideFunction_ 也會複製公用程式函式定義,因此即使定義此函式的區塊類型多次存在,每個公用程式函式也只會存在一次。

更新優先順序

定義公用程式函式時,您也應該更新區塊程式碼產生器中的優先順序 (定義括號插入方式)。

優先順序一律以區塊程式碼產生器傳回的程式碼字串為準。不需關注公用程式函式中的運算子。因此,在前述範例中,valueToCode 呼叫變更為 Order.NONE,而傳回元組已變更為 Order.FUNCTION_CALL