JavaScript中的属性初始化
我用JavaScript创建了一个类,如下所示:JavaScript中的属性初始化,javascript,oop,class,properties,Javascript,Oop,Class,Properties,我用JavaScript创建了一个类,如下所示: var Test = function(){ this.element = null; this.init = function() { if(Test.html == "") { Test.loadHtml(this); return; } this.initElements(); this.someMethodInt
var Test = function(){
this.element = null;
this.init = function() {
if(Test.html == "") {
Test.loadHtml(this);
return;
}
this.initElements();
this.someMethodInternalCall();
};
this.initElements = function() {
// append the loaded html to body
// etc...
this.element = $("some-element-contained-in-loaded-html-apended-to-body");
}
this.someMethodInternalCall = function() {
this.element.css({some:style}); // works in this place
}
this.someMethodExternalCall = function() {
this.element.css({some:style}); // dosn't work in this place
// I mean here this.element is null. WHY?
}
};
Test.html = "";
Test.loadHtml = function() {
// load html content by an ajax request (jQuery $.ajax method)
// and put it in Test.html
// then recall the Test.init ethod
return function(caller) {
Test.html = // load html by ajax... etc...
caller.init();
};
}();
function someUsage(){
var t = new Test();
t.init();
t.element.css({some:style}); // error: t.element is null WHY?
t.someMethodExternalCall(); // error: this.element is null WHY?
}
如您所见,我在上面的代码中进行了解释。为什么在初始化后设置属性时,它只在内部调用中起作用?如何创建可以更改其值的属性
更新:
似乎我必须解释我的代码。问题在于
element
属性,而不是Test.html
或Test.loadHtml
方法或调用它Test.loadHtml
getcurrenctly(您可以测试它)和Test.html
获取加载的html,并将加载的html附加到body
中,依此类推。这是一个JavaScript模式(我忘了它叫什么名字了),现在可以正常工作。唯一错误的是属性初始化-元素
问题在于异步性。当您准备通过AJAX加载HTML时,函数的其余部分将继续
function someUsage(){
var t = new Test();
t.init();
// The following carries on whilst the request is loading it does not wait
t.element.css({some:style}); // This is why I am null
t.someMethodExternalCall(); // This is why I am also null
}
要解决这个问题,您可以使用回调
function someUsage(){
var t = new Test();
t.init(function() {
// I do not continue until the loadHtml request has completed
t.element.css({some:style}); // I am not null anymore
t.someMethodExternalCall(); // I am not null anymore
});
}
您需要修改init函数和loadHtml函数来调用回调函数,而不是调用方对象的init方法,init函数
this.init = function(callback) {
// Using blank Test.html to determine whether the html has been loaded
if(Test.html == "") {
var me = this;
// Call loadHtml with a callback function
Text.loadHtml(function() {
// I want to keep the this reference to the object and callback argument
me.init(callback);
});
// It is loaded so continue set up and then trigger the callback
} else {
this.initElements();
this.someMethodInternalCall();
callback();
}
};
如果您创建了许多这样的测试类,那么仍然会出现问题,因为在其他测试类加载时,每个测试类都会尝试获取HTML
要解决这个问题,您只需要在第一次调用时设置一个标志。任何后续调用都将被忽略,但回调将被记录为在HTML完成加载时调用
Test.loadHtml = function(callback) {
// If already loading roll up callbacks
if(Test.loading) {
// Callback becomes a function that calls the original callback function
// and then the new one
Test.callback = (function(original) {
return function() {
original();
callback();
}
}) (Test.callback);
// First time it has been called set the flag to prevent multiple loads
// and add the callback
} else {
Test.loading = true;
Test.callback = callback;
// Added to illustrate the AJAX callback functionality
ajax("html", function(response) {
Test.html = response;
Test.callback();
});
}
}();
首选的方法是在实例化时强制执行对象有效性,这可以防止这些竞争条件。如果无法有效地构造该类,则抛出错误,这会将围绕操作顺序的复杂性从该类移开。正如您在下面看到的,它没有那么漂亮,您必须自己调用加载步骤(或者让其他东西触发它)
更优雅的解决方案,特别是对于大型应用程序,涉及管理对类的访问。如果不先执行加载步骤,就无法访问该类,这强制要求在实例化该类之前始终完成加载
// views is some object managing the loading of view classes when asked for
// one or more views it will load the required HTML and return the class(es)
// so we can create instances...
views.load("Test", function(Test) {
var t = new Test();
t.element.css({some: style});
t.someMethodExternalCall();
});
您正在执行
caller.init()在loadHtml
中的ajax函数回调中的code>
否则,在加载html之前,init函数将被添加到执行堆栈中(这就是为什么this.element
为空)
这是什么?这是你的密码<代码>Test.html=“”
每当执行脚本时,Test.html将等于NULL…Probelm不在Test.html
中。它是关于元素
调用方
不是未定义的
。请测试代码。它一直工作到第二次调用元素
@apsillers+1是的,在这个问题之后我理解了这一点。但问题是如何处理?我试过var self=this代码>并通过self
而不是this
工作,但如果您可以在类似这样的网站上发布代码的工作示例,则存在的问题将非常有用。您当前的代码不起作用(例如,有一些伪代码,您使用Text.loadHtml
而不是Test.loadHtml
),因此很难解决您的问题。+1并接受感谢。干杯,没问题,很高兴有帮助
// views is some object managing the loading of view classes when asked for
// one or more views it will load the required HTML and return the class(es)
// so we can create instances...
views.load("Test", function(Test) {
var t = new Test();
t.element.css({some: style});
t.someMethodExternalCall();
});
Test.loadHtml = function() {
// load html content by an ajax request (jQuery $.ajax method)
// and put it in Test.html
// then recall the Test.init ethod
return function(caller) {
$.ajax({
url: 'somethinghere',
success: function(data) {
Test.html = data;
caller.init();
}
});
};