标记模板函数不是普通函数,就像构造函数不是普通函数一样。不应该以特殊方式调用它们。构造函数,带有new
, 使用插值字符串文字标记函数。
我们有一个约定,构造函数必须是 Pascal Case,所以调用者很清楚它是一个构造函数。
- 标记函数是否有类似的约定?
- 如果不是,那么强制他们有一个尾随下划线对任何其他约定来说都是模棱两可的吗?
function tagger_(s, name, food) {
return `${s[0]}${name}${s[1]}${food}${s[2]}`
}
const name = 'Dave';
const food = 'ice-cream'
const message = tagger_`Hello World! My name is ${name} and I like ${food} for dinner`;
console.log(message);
this 不是普通函数的参数是第一个参数不是字符串。
const log = console.log;
function tagger_(s) {
console.log(`Has raw property: ${!!s.raw}`);
}
tagger_(`Hello World!`);
tagger_`Hello World!`
同样,该s.raw
属性包含未转义的字符串。没有实际的方法来欺骗这一点。即使可以,这也是非常糟糕的做法。
function tagger_(s) {
console.log(`s.raw: ${s.raw}`);
}
tagger_`This\nhas\tspecial characters`
鸭子打字问题
虽然可以创建一个鸭子类型的对象以传递给该方法,这样它不会立即失败,但 engune 生成的对象的接口可能会扩展(例如,可能escapedRaw
添加了一个属性)。这意味着任何将该方法作为普通函数调用的东西都会中断。
当我们编写一个完全可以控制它的普通函数时,这里不是这种情况,因为s
如果函数的编写者不控制参数类型。