บางครั้งเครื่องมือสร้างโค้ดบล็อกต้องอ้างอิงโค้ดของบล็อกภายในหลายครั้ง
เช่น หากมีบล็อกที่พิมพ์องค์ประกอบสุดท้ายของรายการ คุณจำเป็นต้องเข้าถึงรหัสรายการหลายครั้ง ดังนี้
// 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`;
}