คำสั่งบล็อกอาร์กิวเมนต์การแคช

บางครั้งเครื่องมือสร้างโค้ดบล็อกอาจต้องอ้างอิงโค้ดภายใน บล็อกหลายครั้ง

ตัวอย่างเช่น ถ้าคุณมีบล็อกที่พิมพ์องค์ประกอบสุดท้ายของรายการ คุณจะ จำเป็นต้องเข้าถึงรหัสรายการหลายครั้ง

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