Anweisung blockiert das Caching von Argumenten

Manchmal muss Ihr Blockcode-Generator auf den Code des inneren mehrere Male blockiert werden.

Wenn Sie beispielsweise einen Block haben, der das letzte Element einer Liste ausgibt, mehrere Male auf den Listencode zugreifen müssen:

// 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`;
}

Dies kann jedoch zu Problemen führen, wenn der resultierende Wert des Codes des inneren Blocks oder Nebenwirkungen haben. Wenn der innere Code beispielsweise Funktionsaufruf verwendet wird, kann dieser Code am Ende zu einer Bedingung außerhalb des zulässigen Bereichs führen:

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

Durch die Zuweisung temporärer Variablen können Sie sicherstellen, dass der Code des inneren Blocks nur einmal ausgewertet.

Temporäre Variablen

Eine temporäre Variable speichert den Wert des Codestrings eines inneren Blocks, sodass wird der Code nur einmal ausgewertet und kann dann mehrfach auf den Wert verwiesen werden. Mal.

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`;
}

Der getDistinctName-Aufruf nimmt den gewünschten Variablennamen an und gibt einen Name, der nicht mit benutzerdefinierten Variablen in Konflikt steht.

Redundanten Code reduzieren

Der Nachteil temporärer Variablen besteht darin, dass, wenn der Code des inneren Blocks ein Wert ist, und nicht auf eine Funktion oder einen Ausdruck, erhalten Sie redundanten Code:

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

Für einen saubereren Code können Sie prüfen, ob der Code des inneren Blocks ein Wert ist, und Fügen Sie die temporäre Variable nur ein, wenn dies nicht der Fall ist.

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`;
}