گاهی اوقات مولد کد بلوک شما نیاز دارد چندین بار به کد بلوک داخلی خود ارجاع دهد.
به عنوان مثال، اگر بلوکی دارید که آخرین عنصر یک لیست را چاپ می کند، باید چندین بار به کد لیست دسترسی داشته باشید:
// 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`;
}