简体   繁体   English

你能动态地将局部变量添加到函数中吗?

[英]Can you dynamically add local variables to a function?

I'm using objects to namespace my JavaScript code. 我正在使用对象来命名我的JavaScript代码。 These objects usually contain functions that are called mapping the this -pointer to the object itself using apply . 这些对象通常包含使用apply this -pointer映射到对象本身的函数。 However, I find it inconvenient to use the this -pointer everytime I want to access other functions or properties of the object, especially because in lots of cases I use the new -operator to use function-objects the way you would use classes. 但是,我发现每次我想访问对象的其他函数或属性时都使用this -pointer是不方便的,特别是因为在很多情况下我使用new -operator来使用函数对象,就像你使用类一样。 I would prefer writing new Line() instead if new this.Line() . 如果是new this.Line()我宁愿写new Line() new this.Line()

It would be great if you could add local variables to a function the way php does it with extract (pseudocode following, it's a little more complicated) 如果你可以像php一样用extract方式将局部变量添加到函数中会很棒(伪代码跟随,它有点复杂)

var sample_object = {
  "some_function": function() {}
}

test() {
  extract(sample_object);
  some_function();   // imported from sample_object
}

Is that even possible? 这甚至可能吗?

I'm pretty sure eval is your only answer; 我很确定eval是你唯一的答案; but you need to be aware that if there's any input outside of your control involved, it isn't safe 但是你需要知道,如果你的控制之外有任何输入,那就不安全了

function dynamicArgs (varName, varValue) {
  eval("var " + varName + "=" + JSON.encode(varValue) );
  alert(a);
}

dynamicArgs("a", "value");

You can see the problem with this. 你可以看到这个问题。 How is your function supposed to call the dynamic variable if it doesn't know its name? 如果动态变量不知道它的名字,你的函数应该如何调用? I hardcoded it to the a variable since I pass it in when calling it, but that's not a good solution. 我把它硬编码到一个变量,因为我在调用它时传递它,但这不是一个好的解决方案。 The only solution would be another eval . 唯一的解决方案是另一个eval You really should think about what you need to do and whether this is useful. 你真的应该考虑你需要做什么以及这是否有用。 But it's doable. 但这是可行的。

Here it is in action: http://jsfiddle.net/mendesjuan/GG3Wu/ 在这里它是行动: http//jsfiddle.net/mendesjuan/GG3Wu/

function dynamicArgs (varName, varValue) {
  eval('var ' + varName + "='" + varValue + "';");
  alert(eval(varName));
}

dynamicArgs("f", "Here I am");

Now here's an example like what you're doing, creating a variable from this.MyConstructor http://jsfiddle.net/mendesjuan/AK3WD/ 现在这里有一个像你正在做的例子,从this.MyConstructor创建变量this.MyConstructor http://jsfiddle.net/mendesjuan/AK3WD/

var ns = {
    MyConstructor: function(val) {
       this.prop = val;
    },

    runConstructor: function(val) {
      var Ctor = "MyConstructor";
      eval('var ' + Ctor + ' =  this.' + Ctor);
      return new MyConstructor(val);
    }
}


alert( ns.runConstructor("Hello").prop );

And here's an example if you wanted to import all the values from an object into the scope; 如果您想将对象中的所有值导入范围,这是一个示例;

http://jsfiddle.net/mendesjuan/AK3WD/1/ http://jsfiddle.net/mendesjuan/AK3WD/1/

var ns = {
    MyConstructor: function(val) {
       this.val= val;
    },

    anotherProperty: 5,

    runConstructor: function(val) {
        // Bring all the variables from this into this scope
        for (var prop in this) {
            eval('var ' + prop + ' =  this.' + prop);
        }
        alert('Testing var anotherProperty: ' + anotherProperty);
        var obj =  new MyConstructor(val);
        alert('Created MyConstructor: its prop is ' + obj.val)
    }
}


ns.runConstructor("Hello");

There is controversial with , which has some great applications , but is marginally slow and prone to errors. 还有争议with ,其中有一些优秀的应用 ,但稍微慢而且容易出错。 It throws an error in the strict mode (which you should always opt into) and is going to be deprecated. 它会在严格模式下抛出一个错误(您应该总是选择加入),并且将被弃用。

var sampleObject = {
  someFunction: function() {},
  b: 10
}

with (sampleObject) {
    typeof someFunction // "function"

    var a = 42
    var b = 20
}

sampleObject.a // undefined
sampleObject.b // 20

Note, that new variables defined in a with -block won't be added to the object. 请注意, with -block中定义的新变量不会添加到对象中。 Nevertheless, if the object already had an eponymous property in it, this property would be modified (thanks, @Rocket). 然而,如果对象中已经有一个同名属性,则会修改此属性(感谢@Rocket)。

Just for fun , here's an implementation of extract using eval (which is even more evil than with ). 只是为了好玩 ,这里是使用eval 进行extract的实现 (这比with更邪恶)。 You can do unspeakable things with it, for example if your object has properties like sampleObject['x; while (true) { alert("Hi!") }'] 你可以使用它做不可言说的事情,例如,如果你的对象有像sampleObject['x; while (true) { alert("Hi!") }'] sampleObject['x; while (true) { alert("Hi!") }'] . sampleObject['x; while (true) { alert("Hi!") }']

This is how I did it: 这就是我做的方式:

   function smObject ( object) {
    return function () {
        function getter(prop) {
            return function() {
                return this[prop];
            }
        }

        function setter(prop) {
            return function(data) {
                this[prop]=data;
            }
        }

        for (var o = 0; o < object.length; o++) {
            this[object[o]] = {};
            this['get' + object[o]] = getter(object[o]);
            this['set' + object[o]] = setter(object[o]);
        }
    }
}

now you can instantiate a function like this: 现在你可以实例化一个这样的函数:

var fields = ['Name', 'Id', 'Other', '....' ]
var MyFunction = smObject( fields );
var myObject = new MyFunction();

// getter/setters
myObject.setId(5);
myObject.getId(); // will return 5

Regards, Emanouil 此致,Emanouil

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM