2013-03-21 62 views
2

所以,我想要做這樣的事情:進樣可變進功能的範圍

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'變量。

+0

那麼讓它成爲全球? – 2013-03-21 19:15:35

+0

這樣做的應用程序是什麼?有可能是其他技術人們可能會建議 – 2013-03-21 19:29:51

+1

也許這是一個(複雜)解決方法:http://stackoverflow.com/questions/10060857/is-it-possible-to-achieve-dynamic-scoping-in-javascript-without- evaing-to-eva – bfavaretto 2013-03-21 19:30:27

回答

5

您可以爲該函數或全局變量創建一個參數b

var a = 'a'; 
var dummy = function(b) { 
    ... 
} 

var a = 'a'; 
var b; 
var dummy = function() { 
    ... 
} 

第一個允許您選擇當虛擬函數訪問的變量,第二個允許它隨處訪問。

+3

至於* why:JavaScript使用詞法作用域,因此作用域被附加到函數對象的那一刻函數對象被創建。當函數被調用時,不可能將某些東西注入到作用域中。 – bfavaretto 2013-03-21 19:25:32

1

使用此:

Function.prototype.applyVars = function(scope, params, scope_variables) { 
 
    if (scope_variables) { 
 
    var variable, defVars = []; 
 
    for (variable in scope_variables) { 
 
     if (scope_variables.hasOwnProperty(variable)) { 
 
     defVars.push(variable + '=scope_variables["' + variable + '"]'); 
 
     } 
 
    } 
 
    eval('var ' + defVars.join(',') + ';'); 
 
    return eval('(' + this + ').apply(scope, params);'); 
 
    } 
 
    return this.apply(scope, params); 
 
} 
 

 
// Example 
 

 
function foo(p1) { 
 
    document.write('Variable [p1]: ', p1); 
 
    document.write('<br />'); 
 
    document.write('Variable [x]: ', x); 
 
    document.write('<br />'); 
 
    document.write('Variable [y]: ', y); 
 
} 
 

 
foo.applyVars(this, ['param X'], { x: "1'2\"3", y: false });

或者這樣:

function callWithVars(fn, scope, params, scope_variables) { 
 
    if (scope_variables) { 
 
    var variable, defVars = []; 
 
    for (variable in scope_variables) { 
 
     if (scope_variables.hasOwnProperty(variable)) { 
 
     defVars.push(variable + '=scope_variables["' + variable + '"]'); 
 
     } 
 
    } 
 
    eval('var ' + defVars.join(',') + ';'); 
 
    return eval('(' + fn + ').apply(scope, params);'); 
 
    } 
 
    return fn.apply(scope, params); 
 
} 
 

 
// Example 
 

 
function foo(p1) { 
 
    document.write('Variable [p1]: ', p1); 
 
    document.write('<br />'); 
 
    document.write('Variable [x]: ', x); 
 
    document.write('<br />'); 
 
    document.write('Variable [y]: ', y); 
 
} 
 

 
callWithVars(foo, this, ['param X'], { x: "1'2\"3", y: false });

+1

如果'foo()'在關閉中,並且'foo()'在關閉中調用另一個函數,這將不起作用。 – zixia 2016-10-08 18:47:25

2

所以,我發現了一個快一點的方式做這樣的事情:

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);