是否有一种快速的方式(我的意思是说)从字符串模板中获取通配符?,类似于......
const str = `Hello ${name}, today is ${weekday}!`;
getWildCards(str); // will return ['name', 'weekday']
我正在创建翻译工具,translation
函数不会提前知道通配符。
答案 0 :(得分:1)
修改强>
实际上,事实证明这是一种使用tagged template literals从模板文字中提取参数的本地方法,它允许您使用以下形式的函数来解析模板文字:
function tag(strings, param1, param2, ..., paramN) { ... }
因此,如果不是在模板文字(${ foo }
)的表达式中使用变量,而是使用字符串(${ 'foo' }
),那么如果你这样做:
tag`${ 'a' }${ 'b' } - XXX ${ 'c' }`
strings
将为['', '', ' - XXX ', '']
,您将收到3个参数,其值为'a'
,'b'
和'c'
。
你可以从标签函数中返回任何你想要的东西,所以对你的用例来说一个很好的解决方案就是返回一对[paramsList, closure]
,其中闭包将是一个接收一个对象(map)的函数。 params在原始字符串文字中使用,并使用它们来构建结果字符串。像这样:
function extractParams(strings, ...args) {
return [args, dict => {
return strings[0] + args
.map((arg, i) => dict[arg] + strings[i + 1]).join('');
}];
}
const [params, translate] = extractParams`Hello ${ 'name' }, today is ${ 'weekday' }`;
console.log(params);
console.log(translate({ name: 'Foo', weekday: 'Barday' }));

原始答案:
假设模板字符串被包装到一个函数中,因此它不会抛出ReferenceError
,并且您更改了模板字符串的格式,以便所使用的参数始终是来自对象,您可以使用proxy:
让我们说你有这样的事情:
function getSentence(key, args = {}) {
// Note that for the proxy solution to work well, you need to wrap each of them
// individually. Otherwise you will get a list of all the params from all the
// sentences.
const sentences = {
salutation: (args) => `Hello ${ args.name }, today is ${ args.weekday }!`,
weather: (args) => `Today is ${ args.weather } outside.`,
};
return sentences[key](args) || '';
}
function extractParams(key) {
const params = [];
const proxy = new Proxy({}, {
get: (target, name) => {
params.push(name);
},
});
getSentence(key, proxy);
return params;
}
console.log(extractParams('salutation'));

无论如何,请注意,只有在你的args中只有一个级别深度才会有效,否则你将需要一个代理返回另一个返回另一个代理的代理...并跟踪路径(prop.subprop...
)。他们还应返回function
,为最后一个将在结果字符串中插值的属性返回string
。
function getSentence(key, args = {}) {
// Note that for the proxy solution to work well, you need to wrap each of them
// individually. Otherwise you will get a list of all the params from all the
// sentences.
const sentences = {
salutation: (args) => `Hello ${ args.name }, today is ${ args.a.b.c.d }!`,
weather: (args) => `Today is ${ args.weather } outside.`,
};
return sentences[key](args) || '';
}
function getProxy(params, path = []) {
return new Proxy({}, {
get: (target, name) => {
if (typeof name === 'symbol') {
params.push(path);
return () => ''; // toString();
} else {
return getProxy(params, path.concat(name));
}
},
});
}
function extractParams(key) {
const params = [];
getSentence(key, getProxy(params));
return params;
}
console.log(extractParams('salutation'));