为什么';这个javascript闭包不能像我希望的那样工作吗?

为什么';这个javascript闭包不能像我希望的那样工作吗?,javascript,widget,closures,Javascript,Widget,Closures,我写了这段代码,希望在运行document.ready()后,将search\u form.widget\u date\u range对象上的widget\u controller属性作为一个控制器。令我惊讶的是,它是未定义的。这里出了什么问题 search_form.widget_date_range = (function() { var element_selector = "div.date-range-slider"; var settings = { bounds:

我写了这段代码,希望在运行
document.ready()
后,将
search\u form.widget\u date\u range
对象上的
widget\u controller
属性作为一个控制器。令我惊讶的是,它是
未定义的
。这里出了什么问题

search_form.widget_date_range = (function() {
  var element_selector = "div.date-range-slider";
  var settings = {
    bounds: {
      min: new Date(2003, 0, 1),
      max: new Date()
    },
    defaultValues: {
      min: new Date(2003, 0, 1),
      max: new Date()
    },
    wheelMode: "zoom",
  };
  var widget_controller = {};
  var onDocumentReady = function() {
    widget_controller = $(element_selector).dateRangeSlider(settings);
    widget_controller.on("valuesChanged", onDataChange);
    console.log(widget_controller);
  };
  var onDataChange = function(e, data) {
    // alert("Value just changed. min: " + data.values.min + " max: " + data.values.max);
    $("form#searching").trigger("submit");
  };
  return {
    onDocumentReady: onDocumentReady,
    widget_controller: widget_controller
  };
})();

$(document).ready(function() {
    ...
    search_form.widget_date_range.onDocumentReady();
});

我认为您缺少JavaScript中引用的一点:

var search_form={};
search_form.widget_date_range = (function() {
   // Whatever code here

  // widget_controller variable references an empty object
  var widget_controller = {}; // #A
  var onDocumentReady = function() {
    // Here you redefine widget_controller,
    // but not the returned_object.widget_controller property
    widget_controller = $(element_selector).dateRangeSlider(settings); #B
    widget_controller.on("valuesChanged", onDataChange);
    console.log(widget_controller);
  };
  // Whatever here
  return {
    onDocumentReady: onDocumentReady,
    // returned_objet.widget_controller references the empty object
    widget_controller: widget_controller #C
  };
})();
一种解决办法可以是:

  ...
  return {
    onDocumentReady: onDocumentReady,
    get widget_controller() {
      return widget_controller; #D
    }
  };
  ...
这里是JSFIDLE演示:

编辑:(似乎需要更多解释)

第一:
{get property(){}}
语法来自ES5,您可以在这里找到MDN上的文档:

您可以使用另一种语法来实现ES3的相同功能,如下所述:(但仅当您希望支持IE8及以下版本时才使用此语法-我希望您不必这样做)

#A
声明变量widget_控制器并将其设置为(几乎)空对象(
{}
);(我这么说几乎是因为它仍然有一个带有一些继承方法和属性的原型)

#C
中,您将对象文本(将由闭包返回)的属性
widget_controller
设置为空对象的引用

#B
(发生在
#C
之后)重新定义闭包的小部件控制器,但不重新定义函数返回的对象的小部件控制器,它仍然引用空对象的值

在我的代码中,在
#D
中,每当访问闭包返回的对象的属性widget_控制器时,都会返回闭包的相同widget_控制器


我希望它更清楚,尽管我不是很确定…

没有调用onDocumentReady()函数?这就是正在发生的事情吗?在您尝试写入widget\u date\u range属性之前,搜索表单是否有值?这可能是起重变化的迹象。您是否在ready函数的任何地方声明了“var search\u form”?@Marcos。谢谢Marcos,是的,我从document.ready中调用了它。@JohnKossa:是的,搜索表单是从另一个自调用函数返回的对象。天哪,它工作了!亲爱的拉鲁斯,我的版本到底出了什么问题?这不是一个典型的闭包吗?onDocumentReady函数中的widget_控制器应该引用它的直接外部作用域,它将widget_控制器定义为一个空对象{}?为什么它必须重新定义它?我正在抓挠我的头。另外,你能告诉我“get widget_controller()”部分是如何工作的吗?我试着在谷歌上搜索,但没有找到任何相关信息。非常感谢。有人能解释一下为什么我的第一个版本不起作用吗?这对我来说似乎是一个完美的结束。非常感谢。很抱歉耽搁了,我编辑了我的答案,添加了一些解释。我希望你能更好地理解。如果没有,请毫不犹豫地说出来。@Iaruiss:现在很清楚了。非常感谢你详细而透彻的解释。我真的很喜欢读它!