为什么这个javascript关闭不像我希望的那样工作?

时间:2016-01-23 00:47:54

标签: javascript widget closures

我编写了这段代码,希望在运行document.ready()部分之后,widget_controller对象上的search_form.widget_date_range属性将成为控制器。令我惊讶的是,它是undefined。这里出了什么问题?

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();
});

1 个答案:

答案 0 :(得分:1)

我认为你错过了关于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
    }
  };
  ...

这里的JSFiddle演示:https://jsfiddle.net/xgya3mzh/2/

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

第一: { get property() {} }语法来自ES5,您可以在此处找到MDN上的文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

您可以使用另一种语法完成相同的ES3,在此解释:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineGetter(但只有在您希望支持IE8及以下时才使用此语法 - 我希望您不必这样做。)

#A,您声明变量widget_controller并将其设置为(几乎)空对象({}); (我说几乎是因为它仍然有一些带有一些继承方法和属性的原型)。

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

#B #C之后,您重新定义了闭包的widget_controller,但是您没有重新定义该函数返回的对象的widget_controller,仍然引用空对象的值。

在我的代码中,在#D中,每当您访问闭包返回的对象的属性widget_controller时,都会返回闭包的相同widget_controller。

我希望它更清楚,虽然我不太确定......