JavaScript闭包&;可变范围
我很难理解JS中闭包和变量范围的概念。具体地说,如何访问类中的深度嵌套的JavaScript闭包&;可变范围,javascript,jquery,closures,scope,Javascript,Jquery,Closures,Scope,我很难理解JS中闭包和变量范围的概念。具体地说,如何访问类中的深度嵌套的styleData变量,然后访问从该类创建的对象 我肯定我这里还有一些其他的错误,所以请插进来,在你认为合适的地方纠正我。谢谢 var BuildJSON = { convert: function() { $.ajax({ type: "GET", url: "style2.xml", dataType: "xml",
styleData
变量,然后访问从该类创建的对象
我肯定我这里还有一些其他的错误,所以请插进来,在你认为合适的地方纠正我。谢谢
var BuildJSON = {
convert: function() {
$.ajax({
type: "GET",
url: "style2.xml",
dataType: "xml",
success: function(xml) {
var styleData = $.xml2json(xml);
return styleData; // Do I need to return this somehow?
}
//How to get access to styleData??
});
},
styleData: this.convert();
};
var myClass = function() {
this.info = BuildJSON.styleData;
};
var myObject = new myClass;
alert(myObject.info.Style[0].name);
JavaScript中的闭包是函数,因此在函数范围内声明的任何内容都只能在该函数内可见 在您的示例中,
styleData
是本地的,它属于success
函数,不能在其他任何地方访问。最简单的解决方案是在BuildJSON
范围的顶部声明该变量,在这种情况下,由于您将该对象声明为对象文本,因此可以将其初始化为该对象的属性:
this.styleData = '',
...
success: function(xml) {
BuildJSON.styleData = $.xml2json(xml);
}
这种方法的“问题”在于styleData
是公共的,而这可能不是您想要的。如果您想在BuildJSON中使用该变量,但不想让它公开访问,那么模块模式将起到帮助作用
var BuildJSON = (function(){
var styleData = '', // local
convert = function(){ ... } // You can use style data here
return {
convert: convert // Return only stuff you want to be public
}
}())
我想说,这里的大问题更多地是关于AJAX调用的异步编程DU,而不是回调本身 您可以做的一件事就是从ajax回调显式地设置styleData。注意如何从内部作用域访问和修改外部作用域中的“that”变量
var BuildJSON = {
convert: function() {
var that = this; // inner callbacks get separate "this"
// variables so we save the BuildJSON in a separate variable.
$.ajax({
type: "GET",
url: "style2.xml",
dataType: "xml",
success: function(xml) {
that.styleData = $.xml2json(xml);
}
});
}
};
BuildJSON.convert();
虽然这样做很简单,但它有一个缺点,即只允许您在converts完成运行后读取“styleData”属性,并且您编写代码的方式无法知道ajax调用已经完成(其他方法是使用setinterval轮询styleData变量,但这很愚蠢)
从异步函数“返回”内部值有两种主要方法。一种方法是像$.ajax本身那样,将函数转换为延续传递样式。这样,当您完成styleData的计算时,您将收到一个函数来调用它,而不是返回styleData结果
convert: function( onStyleData ) {
$.ajax({
// ...
success: function(xml) {
var styleData = $.xml2json(xml);
onStyleData( styledata ); // <---
}
});
};
BuildJSON.convert(function(styledata){
console.log('got styledata', styledata)
})
变量
myObject
和BuildJSON
是否预先声明?在什么之前?BuildJSON是一个对象文字,myObject是从myClass创建的新对象,对吗?在上面发布的代码之前。如果这两个变量第一次出现在上面的代码中,您必须在它们前面放置一个var
,如:var BuildJSON={…
和var myObject=…
这里的一个问题是样式数据是通过Ajax检索的,因此警报(myObject.info.style[0].name);
将始终抛出,因为实例是在同一调用堆栈中创建的,而Ajax响应处理程序还无法执行。如果要使用Ajax响应中的样式数据,必须从Ajax响应处理程序中执行。
var styleDataPromise = dojo.xhr({
url: /*...*/,
load: function(data){
return xmlToJSON(xml);
}
})
styleDataPromise.then(function(styleData){
console.log('got styledata', styleData)
})