문 블록 캐싱 인수

블록 코드 생성기가 내부 여러 번 차단할 수 있습니다.

예를 들어 목록의 마지막 요소를 출력하는 블록이 있는 경우 목록 코드에 여러 번 액세스해야 합니다.

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