我的代码本身非常好用:
var Person = {
getName: function() {
alert("Johnny");
}
};
var myContext = "Person";
var theCodeToExecute = myContext + ".getName()";
var theFunctionItself = new Function(theCodeToExecute);
theFunctionItself();
但是当我把它放在jQuery中时,它就会停止工作。
$(document).ready(function() {
//Where the code should be.
});
我知道已经回答了非常相似的问题,但没有一个问题解决了这个问题。
编辑:
感谢大家的回答。我想我已经把我的问题缩小了很多,以至于我的意图非常清楚。这是我想要实现的更清晰的版本:
var Road = {
House: function(color, size, neighbor){
this.color = color;
this.size = size;
this.neighbor = neighbor;
}
};
Road.House.prototype.getSize = function() {
alert(this.size);
};
Road.House.prototype.getNeighborSize = function() {
var theNeighbor = this.neighbor;
var codeToExecute = theNeighbor + ".getSize()";
var tmpFunc = new Function(codeToExecute);
tmpFunc(); //this only works when outside of jQuery.
};
var house1 = new Road.House("blue", "small", "house2");
var house2 = new Road.House("red", "huge", "house3");
house1.getNeighborSize(); //this successfully returns "huge" when outside of jQuery.
同样,这本身非常好用,但在jQuery中不起作用,我需要它在jQuery中工作,因为我的函数的最终版本将使用大量的jQuery代码。再次感谢!
最后编辑:
感谢Felix的出色帮助。似乎有一个最后的问题。如果在我正在查询的房子之前宣布邻居,我只能得到邻居的大小。
var house1 = new Road.House("red", "big", house2);
var house2 = new Road.House("blue", "huge", house3);
var house4 = new Road.House("blue", "small", house4);
var house3 = new Road.House("blue", "little", house1);
house1.getNeighborSize(); //this doesn't work.
house3.getNeighborSize(); //this works
再次感谢!!
答案 0 :(得分:4)
使用new Function
创建功能时,将在全局范围中创建该功能。
即它无法访问您在内部 ready
回调中创建的变量。
// global scope
$(document).ready(function() {
// ready callback scope
});
引用MDN这里的黄色大框:
注意 :使用
Function
构造函数创建的函数不会为其创建上下文创建闭包;它们总是在全球范围内创建。运行它们时,它们只能访问自己的局部变量和全局变量,而不能访问调用Function构造函数的范围。这与使用eval
和函数表达式代码不同。
解决方案:
Person
。eval
代替new Function
。最好的:
Person.getName()
。 即使你认为你必须评估代码,你可能不会,但如果你不解释你真正想要实现的目标,我们无法帮你找到替代方案。
那么,解决问题的方法不是尝试动态引用变量,而是将对邻居的引用传递给构造函数:
var house2 = new Road.House("red", "huge");
var house1 = new Road.House("red", "huge", house2);
然后该函数看起来像
Road.House.prototype.getNeighborSize = function() {
if (this.neighbor) {
this.neighbor.getSize();
}
};
如果在构建时无法传递对邻居的引用,则可以创建一个setter:
Road.House.prototype.setNeighbor = function(neighbor) {
this.neighbor = neighbor;
};
答案 1 :(得分:0)
好吧,如果您尝试调用某个方法,则会出现一些错误。正如费利克斯所提到的,你应该避免像这样动态评估Javascript。首先,假设您只想调用getName方法,我将从更正后的代码开始。
$(document).ready(function() {
var Person = {
getName: function() {
alert("Johnny");
}
};
Person.getName();
});
您无需将Person重新分配给新变量,您可以直接在此处访问它。您还将Person放在引号中,这意味着您的myContext变量引用了一个字符串,其中包含单词" Person"。
现在,我认为你真正想要做的是构建一个构造函数,从你使用new开始。
以下是实际完成的方式:
$(document).ready(function () {
//You need to make it a function that returns an object
var Person = function (name) {
return {
getName: function () {
alert(name);
}
}
};
//Then we create an instance of Person and pass in the name as an argument
var johnny = new Person('Johnny');
johnny.getName();
});
您将看到,不是将Person设为对象,而是将其作为返回对象的函数,并使用函数参数作为名称的占位符。通过这种方式,我们可以创建尽可能多的人,而且我们不必每次都重新定义Person。例如,如果我们想要再创造一些人,我们就是这样做:
var sam = new Person('Sam');
var jim = new Person('Jim');
现在sam.getName()会警告Sam'和jim.getName()会警告Jim'。