有时,您的块代码生成器需要多次引用其内部块的代码。
例如,如果您有一个获取列表最后一个元素的块,则需要多次访问列表代码:
// 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
,返回元组已更改为 Order.FUNCTION_CALL
。