我正在使用对象来命名我的JavaScript代码。这些对象通常包含使用apply
将this
指针映射到对象本身的函数。然而,每次我想访问对象的其他函数或属性时,我都发现使用this
-指针很不方便,尤其是因为在很多情况下,我使用new
-运算符来使用函数对象,就像使用类一样。如果是new this.Line()
,我更喜欢写new Line()
。
如果您可以像php使用extract
(下面是伪代码,它有点复杂)那样向函数添加局部变量,那就太好了
var sample_object = {
"some_function": function() {}
}
test() {
extract(sample_object);
some_function(); // imported from sample_object
}
这可能吗?
我很确定eval
是您唯一的答案;但你需要意识到,如果有任何超出你控制范围的输入,是不安全的
function dynamicArgs (varName, varValue) {
eval("var " + varName + "=" + JSON.encode(varValue) );
alert(a);
}
dynamicArgs("a", "value");
你可以看到这个问题。如果函数不知道动态变量的名称,该如何调用它?我把它硬编码为一个变量,因为我在调用它时传递了它,但这不是一个好的解决方案。唯一的解决方案是另一个eval
。你真的应该考虑一下你需要做什么,以及这是否有用。但这是可行的。
它在这里发挥作用:http://jsfiddle.net/mendesjuan/GG3Wu/
function dynamicArgs (varName, varValue) {
eval('var ' + varName + "='" + varValue + "';");
alert(eval(varName));
}
dynamicArgs("f", "Here I am");
现在有一个类似于您正在做的示例,从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 );
这里有一个例子,如果您想将对象中的所有值导入到范围中;
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");
有一个有争议的with
,它有一些很好的应用程序,但速度稍慢,容易出错。它在严格模式下抛出一个错误(您应该始终选择该模式),并将被弃用。
var sampleObject = {
someFunction: function() {},
b: 10
}
with (sampleObject) {
typeof someFunction // "function"
var a = 42
var b = 20
}
sampleObject.a // undefined
sampleObject.b // 20
注意,with
块中定义的新变量不会添加到对象中。尽管如此,如果对象中已经有同名属性,则会修改此属性(谢谢@Rocket)。
只是为了好玩,这里有一个使用eval
的extract
的实现(它甚至比with
更邪恶)。您可以用它做一些无法形容的事情,例如,如果您的对象具有类似sampleObject['x; while (true) { alert("Hi!") }']
的属性。
我就是这样做的:
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]);
}
}
}
现在,您可以实例化这样的函数:
var fields = ['Name', 'Id', 'Other', '....' ]
var MyFunction = smObject( fields );
var myObject = new MyFunction();
// getter/setters
myObject.setId(5);
myObject.getId(); // will return 5
谨致问候,Emanouil