最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Inject variable into function's scope - Stack Overflow

programmeradmin5浏览0评论

So, I want to do something like this:

    var a = 'a';

    var dummy = function() {

        // Print out var 'a', from the scope above
        console.log('Dummy a: ' + a);

        // Print out 'b', from the 'pelled' 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:
        dummypel(this, [], {b: 'injected!'});

    })();

But that won't work.

I don't actually want a function to be able to reach 2 scopes, I DO want to be able to set the 'b' variable used inside the dummy function from the outside.

So, I want to do something like this:

    var a = 'a';

    var dummy = function() {

        // Print out var 'a', from the scope above
        console.log('Dummy a: ' + a);

        // Print out 'b', from the 'pelled' 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.pel(this, [], {b: 'injected!'});

    })();

But that won't work.

I don't actually want a function to be able to reach 2 scopes, I DO want to be able to set the 'b' variable used inside the dummy function from the outside.

Share Improve this question asked Mar 21, 2013 at 19:14 Jelle De LoeckerJelle De Loecker 22k29 gold badges104 silver badges146 bronze badges 3
  • Whats the application for doing this? There might be other techniques people could suggest – user2033671 Commented Mar 21, 2013 at 19:29
  • 1 Maybe this is a (plex) workaround: stackoverflow./questions/10060857/… – bfavaretto Commented Mar 21, 2013 at 19:30
  • I mainly want to see if it's possible. Well, I actually want to use it in a node.js MVC. I don't like that every action has set arguments, this would have been nicer. @bfavaretto has shown me a nice workaround, though I fear using eval() will be too much of a performance hit :) – Jelle De Loecker Commented Mar 21, 2013 at 19:38
Add a ment  | 

4 Answers 4

Reset to default 6

You can make b a parameter for the function, or a global variable.

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

or

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

The first allows you to choose when the dummy function has access to the variable, the second allows it to be accessed everywhere.

So, I found a little faster way to do such a thing:

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

Use this:

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

Or this:

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

the @vasiliy's solution extended to inject any function

function injectScope(ctx, func) {
  var newBody = [];

  for (var k in ctx) {
    var i = "  var " + k + " = ctx['" + k + "'];";
    newBody.push(i);
  }

  let res = (func + '').replace(/^(.*?)\)\s*{(.*)$/gms, `return(\n$1){\n${newBody.join('\n')}\n$2)`);
  // console.log(res)
  let F = new Function("ctx", res);
  return F(ctx);
}

function sum(t) {
  return foo + bar * t
}

var injectedSum = injectScope({ "foo": 10, "bar": 100 }, sum)
// console.log(injectedSum+'')  
console.log(injectedSum(50));
发布评论

评论列表(0)

  1. 暂无评论