admin 管理员组文章数量: 1086864
I'd like to implement a string formatter. I've used formatters that take string like "the quick, brown {0} jumps over the lazy {1}"
where you pass in parameters whose cardinal location is used to replace the braced integers.
I'd love to be able to do something more like "the quick, brown {animal1} jumps over the lazy {animal2}"
where animal1 and animal2 are variables and are simply evaluated. I got the following method implemented, but then realized that eval is not going to work because it doesn't use the same scope.
String.prototype.format = function() {
reg = new RegExp("{([^{}]+)}", "g");
var m;
var s = this;
while ((m = reg.exec(s)) !== null) {
s = s.replace(m[0], eval(m[1]));
}
return s;
};
- Is there a way to do this without using eval (doesn't seem like it).
- Is there a way to give eval the closure so it gets scope? I tried
with(window)
andwindow.eval()
, but that didn't work.
I'd like to implement a string formatter. I've used formatters that take string like "the quick, brown {0} jumps over the lazy {1}"
where you pass in parameters whose cardinal location is used to replace the braced integers.
I'd love to be able to do something more like "the quick, brown {animal1} jumps over the lazy {animal2}"
where animal1 and animal2 are variables and are simply evaluated. I got the following method implemented, but then realized that eval is not going to work because it doesn't use the same scope.
String.prototype.format = function() {
reg = new RegExp("{([^{}]+)}", "g");
var m;
var s = this;
while ((m = reg.exec(s)) !== null) {
s = s.replace(m[0], eval(m[1]));
}
return s;
};
- Is there a way to do this without using eval (doesn't seem like it).
- Is there a way to give eval the closure so it gets scope? I tried
with(window)
andwindow.eval()
, but that didn't work.
3 Answers
Reset to default 6For a usage like var result = "This will get formatted with my {name} and {number}".format({name: "TetsujinOni", number: 1234});
Why not head off in this direction:
String.prototype.format = function(scope) {
reg = new RegExp("{([^{}]+)}", "g");
var m;
var s = this;
while ((m = reg.exec(s)) !== null) {
s = s.replace(m[0], scope[m[1]]);
}
return s;
};
All global variables are defined in the window
object, so you should be able to do this without eval:
String.prototype.format = function(scope) {
scope = scope || window; //if no scope is defined, go with window
reg = new RegExp("{([^{}]+)}", "g");
var m;
var s = this;
while ((m = reg.exec(s)) !== null) {
s = s.replace(m[0], scope[m[1]]);
// ^^^^^^^^^^^
}
return s;
};
Here you should also simply be able to change window
to what scope you feel like.
If variables are not in the global scope, but rather in your current scope, you might want to read this or go with Tetsujin's solution.
Oh yes... the holy grail of javascript variable interpolation... You actually can pass the local scope around by using dark magic like this:
String.prototype.format = function(_eval) {
return this.replace(/{(.+?)}/g, function($0, $1) {
return _eval($1);
})
};
function foo() {
var a = 123, b = 456;
s = "a is {a} and a+b={a+b}".format(function(x) {return eval(x)})
console.log(s) // a is 123 and a+b=579
}
I'm afraid there's no way to make the format
call less verbose.
And here's a version that requires explicit scope passing, but still allows for arbitrary expressions in {...}
's:
String.prototype.format2 = function(scope) {
eval(Object.keys(scope).map(
function(x) { return "var " + x + "=scope." + x
}).join(";"));
return this.replace(/{(.+?)}/g, function($0, $1) {
return eval($1);
})
};
function foo() {
var a = 123, b = 456;
s = "a is {a} and a+b={a+b}".format2({a:a, b:b})
console.log(s) // a is 123 and a+b=579
}
You are not expected to understand this.
本文标签: javascriptHow to implement a string formatter with variable namesStack Overflow
版权声明:本文标题:javascript - How to implement a string formatter with variable names - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1744018098a2519296.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论