Javascript 将变量注入函数';s范围
所以,我想这样做:Javascript 将变量注入函数';s范围,javascript,node.js,Javascript,Node.js,所以,我想这样做: var a = 'a'; var dummy = function() { // Print out var 'a', from the scope above console.log('Dummy a: ' + a); // Print out 'b', from the 'compelled' scope console.log('Dummy b: ' + b); }
var a = 'a';
var dummy = function() {
// Print out var 'a', from the scope above
console.log('Dummy a: ' + a);
// Print out 'b', from the 'compelled' scope
console.log('Dummy b: ' + b);
}
(function() {
var b = 'otherscope';
// I know apply won't work, I also don't want to merge scopes
dummy.apply(this);
// I want something like this:
dummy.compel(this, [], {b: 'injected!'});
})();
但那是行不通的
实际上,我并不希望函数能够达到2个作用域,我希望能够从外部设置虚拟函数内部使用的“b”变量。您可以将
b
设置为函数的参数或全局变量
var a = 'a';
var dummy = function(b) {
...
}
或
第一个选项允许您选择虚拟函数何时可以访问变量,第二个选项允许在任何地方访问变量。使用以下选项:
Function.prototype.applyVars=函数(范围、参数、范围变量){
if(范围变量){
var变量,defVars=[];
for(范围中的变量\u变量){
if(作用域变量.hasOwnProperty(变量)){
push(variable+'=scope_variables[“'+variable+'”]);
}
}
eval('var'+defVars.join(',')+';');
返回eval(“(“+this+”).apply(范围,参数);”);
}
返回此。应用(范围、参数);
}
//范例
功能foo(p1){
write('变量[p1]:',p1);
文件。写入(“
”);
document.write('变量[x]:',x);
文件。写入(“
”);
document.write('变量[y]:',y);
}
foo.applyVars(this,['param X'],{X:'1'2\'3',y:false})
因此,我找到了一种更快的方法来做这件事:
var C = function(ctx, funcBody){
var newBody = [];
for(var k in ctx){
var i = "var "+k + " = ctx['"+k+"'];";
newBody.push(i);
}
var res = "return function(t){ " +funcBody+ " }";
newBody.push(res);
var F = new Function("ctx", newBody.join('\n'));
return F(ctx);
}
var newFunction = C({"foo":10, "bar":100}, "return foo+bar*t")
newFunction(50);
至于原因:JavaScript使用词法作用域,因此在创建函数对象时作用域就被附加到函数对象。调用函数时不可能向作用域中注入任何内容。应用程序是如何做到这一点的?可能还有其他技术,人们可能会建议这可能是(复杂的)解决方法:我主要想看看是否可能。实际上,我想在node.js MVC中使用它。我不喜欢每个操作都设置参数,这会更好。@bfavaretto向我展示了一个很好的解决方法,尽管我担心使用eval()会对性能造成太大的影响:)如果
foo()
位于一个闭包内,并且foo()
调用该闭包内的另一个函数。
var C = function(ctx, funcBody){
var newBody = [];
for(var k in ctx){
var i = "var "+k + " = ctx['"+k+"'];";
newBody.push(i);
}
var res = "return function(t){ " +funcBody+ " }";
newBody.push(res);
var F = new Function("ctx", newBody.join('\n'));
return F(ctx);
}
var newFunction = C({"foo":10, "bar":100}, "return foo+bar*t")
newFunction(50);