陳述式會封鎖快取引數

有時候,區塊程式碼產生器需要參照其內部程式碼 反覆封鎖

舉例來說,如果您的區塊會輸出清單的最後一項元素, 必須多次存取清單程式碼:

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

  // listCode gets referenced twice.
  return `print(${listCode}[${listCode}.length - 1]);\n`;
}

但是,如果內部區塊程式碼的結果值為 或是有副作用舉例來說,如果內部程式碼實際上 則這個特定程式碼最終可能會超出範圍的條件:

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

指派給臨時變數可讓您確保內部區塊的程式碼 只會評估一次

暫時變數

暫時變數會儲存內部區塊程式碼字串的值, 程式碼只會「評估」一次,之後該值就可以參照多個 次。

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

// Correct block-code generator.
javascriptGenerator.forBlock['print_last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);
  const listVar = generator.nameDB_.getDistinctName(
      'temp_list', Blockly.names.NameType.VARIABLE);

  // listCode only gets evaluated once.
  const code = `var ${listVar} = ${listCode};\n`;
  return `print(${listVar}[${listVar}.length - 1]);\n`;
}

getDistinctName 呼叫會使用您想要的變數名稱,然後傳回 且未與任何使用者定義的變數衝突。

減少多餘的程式碼

暫時變數的缺點是如果內部區塊的程式碼是值 而不是函式或運算式,就會得到多餘的程式碼:

// Assigning to temp_list is unnecessary.
var temp_list = foo;
print(temp_list[temp_list.length - 1]);

如要產生更簡潔的程式碼,請檢查內部區塊的程式碼是否為值,並 如果不是這個暫時性變數,則只顯示該變數。

if (listCode.match(/^\w+$/)) {
  const code = `print(${listCode}[${listCode}.length - 1]);\n`;
} else {
  const listVar = generator.nameDB_.getDistinctName(
      'temp_list', Blockly.names.NameType.VARIABLE);
  const code = `var ${listVar} = ${listCode};\n`;
  code += `print(${listVar}[${listVar}.length - 1]);\n`;
}