有时,区块码生成器需要引用其内部代码的 进行多次屏蔽
例如,如果您有一个用于获取列表最后一个元素的块,则需要 来多次访问列表代码:
// Incorrect block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);
// listCode gets referenced twice.
const code = `${listCode}[${listCode}.length - 1]`;
return [code, Order.MEMBER];
}
但是,如果内部代码块代码的结果值是 或存在副作用。例如,如果内部代码实际上是 函数调用,此特定代码最终可能会出现超出范围的情况:
randomList()[randomList().length - 1]
通过使用实用函数,您可以确保内部代码块的代码只是 只评估一次。
实用函数
实用函数是开发者定义的函数,包含在 生成的代码字符串您可以使用它们来确保内部代码块代码 只评估一次,就可以多次引用该值。
import {javascriptGenerator, Order} from 'blockly/javascript';
// Correct block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
const listCode = generator.valueToCode(block, 'LIST', Order.NONE);
const functionName = generator.provideFunction_(
'list_lastElement',
[
`function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`,
` return list[list.length - 1];`,
`}`
]
);
// listCode only gets evaluated once.
const code = `${functionName}(${listCode})`;
return [code, Order.FUNCTION_CALL];
}
提供函数
您可以使用以下代码在块码生成器内定义实用函数:
provideFunction_
。它接受您想要的实用函数名称,以及
一个定义函数用途的代码字符串数组。它会返回
修改为非实用函数后(可能)
与用户定义的函数冲突。
provideFunction_
还会对实用函数定义进行去重处理,以便每个
实用函数仅存在一次,即使定义该函数的块类型存在也是如此
。
更新优先级
定义实用函数时,还应更新优先级函数 (用于定义括号的插入方式) 块代码生成器。
优先级始终基于块码返回的代码字符串
生成器。而不关注实用函数中的运算符。因此,在
上例中的 valueToCode
调用已更改为 Order.NONE
,
return 元组已更改为 Order.FUNCTION_CALL
。