让我们想象您正在构建一个银行应用程序后端。您想使用返回余额的字符串来响应用户,但是您忘记添加()
。
class User {
constructor() {console.log("ctor")}
balance() { console.log("secret balance code")}
}
然后在引用用户时,而不是这样写:
const userA = new User();
return `Your balance is $${userA.balance()}`;
我不小心写了这个:
const userA = new User();
return `Your balance is $${userA.balance}`;
可悲的是输出:
'Your balance is balance() { console.log("secret balance code")}'
哪个泄漏了源代码。
答案 0 :(得分:1)
一种解决方法是像这样覆盖所有功能的toString
:
> Function.prototype.toString = () => {return "bla"}
[Function]
> '' + new User().balance
'bla'
答案 1 :(得分:1)
您无需担心,如果您忘记了某些内容,则进行测试将有助于找到它。当他有一个认真的项目时,没有人在没有测试的情况下将其部署到生产中。编写测试比尝试纠正语言行为要好。
答案 2 :(得分:0)
响应请求时,无疑将通过某种序列化器运行响应。 JSON,CBOR等。在该层进行处理。
幸运的是,如果您要返回JSON数据,则该数据已经处理过:
JSON.stringify(someFunction);
// undefined
如果您确实要返回纯文本字符串,则仍然可以使用这样的层来确保不释放函数。
答案 3 :(得分:0)
我有一个绝对比原始模板慢的解决方案,但是可以解决了。
所以基本上,我只是发送一个上下文对象,该对象包含要解析的所有字符串。在实际替换字符串之前,我只需检查参数的类型。
function resolveTemplates(str, args){
if(args && Array.isArray(args) && args.length){
args.forEach((argument) => {
// check here for any unwanted types
if(typeof arg === 'function'){
throw new Error('Cannot send function to create raw Strings')
}
})
}
const rx = /\{([^{}]*)\}/g;
let match = {};
let matches = [];
while(match = rx.exec(str)){
matches.push(match)
}
matches.reverse();
matches.forEach(function(match){
const key = match[1];
const index = match.index;
str = str.slice(0, index) + args[key] + str.slice(index + 2 + key.length)
})
return str;
}
resolveTemplates('Hello! My name is {firstName} {lastName}', {firstName: 'Shobhit', lastName: 'Chittora'})
PS:您可以调用函数,而不是将函数作为参数抛出错误。但是将功能绑定到正确的上下文可能是思考的开销,并且通常不建议这样做。