标记的模板函数不是 normal 函数,与构造函数不是常规函数的方式相同。绝不能以特殊方式调用它们。具有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);
此参数不是 normal 函数的原因是,第一个参数不是字符串。
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`
鸭子输入问题
虽然有可能创建一个鸭子类型的对象以传递到该方法中,从而不会立即失败,但是引擎生成对象的接口可能会扩展(例如,一个escapedRaw
属性是添加)。这意味着将任何作为正常功能调用该方法的东西都破坏了。
当我们编写一个完全由普通函数控制的函数时,此处不是这种情况,因为s
参数类型不受该函数的编写者控制。