我正在使用这个脚本,它允许你使用插值变量构建正则表达式。目前我得到了这个并且效果很好:
function sRegExp( regex, vars ) {
vars = Array.prototype.slice.call( arguments, 1 );
regex = regex.toString();
var newRegex = regex.replace(/(^\/|\/$|\/([igm]+)$)/g, '')
.replace( /#\{(\d)\}/g, function( a, b ) { return vars[ +b ]; });
var mods = regex.match( /\/([igm]+)$/ );
return new RegExp( newRegex, mods ? mods[1] : '' );
}
我这样使用它:
function func() {
var foo = 'lol';
return sRegExp( /baz #{0}/i, foo );
}
console.log( func() ); //=> /baz lol/i
我想通过使用变量名来改进这个脚本,而不是必须使用索引并将变量作为参数传递,所以我想到使用eval
,所以我摆脱了vars
和稍微重构了一下代码:
function sRegExp( regex ) {
regex = regex.toString();
var newRegex = regex.replace(/(^\/|\/$|\/([igm]+)$)/g, '')
.replace( /#\{(\w+)\}/g, function( a, b ) { return eval( b ); });
__^__ __^__
var mods = regex.match( /\/([igm]+)$/ );
return new RegExp( newRegex, mods ? mods[1] : '' );
}
现在上一个例子的问题是:
console.log( func() ); //=> foo is not defined
但在全球范围内......
var foo = 'lol';
function func() {
return sRegExp( /baz #{foo}/i );
}
console.log( func() ); //=> /baz lol/i
如何设置eval
的上下文。我试过eval.call(func)
,但这显然不起作用。有什么想法吗?
答案 0 :(得分:2)
您无法设置eval
的范围。它继承了本地执行上下文,因此只能看到它的调用上下文看到的内容(在这种情况下,在func
内)。不幸的是,没有办法解决这个问题。
当控件进入eval代码的执行上下文时,前一个活动执行上下文(称为调用上下文)用于确定作用域链,变量对象和此值。如果没有调用上下文,则初始化作用域链,变量实例化以及确定此值的操作与全局代码一样。
答案 1 :(得分:2)
我不是eval
的粉丝,也不是混乱的全球空间。所以,我的回答是有偏见的。
您可以将命名变量作为参数传递。
function func() {
return sRegExp( /baz #{foo}/i, { foo: "lol" } );
}
和
function sRegExp( regex, vars ) {
...
var newRegex = regex.replace(/(^\/|\/$|\/([igm]+)$)/g, '')
.replace( /#\{(\w+)\}/g, function( a, b ) { return vars[b]; });
...
}