简体   繁体   English

为什么这个javascript闭包无法正常运行?

[英]Why doesn't this javascript closure work as I hoped?

I wrote this piece of code, hoping that after running the document.ready() part the widget_controller property on search_form.widget_date_range object will become a controller. 我编写了这段代码,希望在运行document.ready()部分后, search_form.widget_date_range对象上的widget_controller属性将成为控制器。 To my surprise, it is undefined . 令我惊讶的是,它是undefined What is going wrong here? 这是怎么了?

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

I think you are missing a point about references in JavaScript: 我认为您缺少关于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
  };
})();

One solution could be: 一种解决方案可能是:

  ...
  return {
    onDocumentReady: onDocumentReady,
    get widget_controller() {
      return widget_controller; #D
    }
  };
  ...

JSFiddle demo here: https://jsfiddle.net/xgya3mzh/2/ JSFiddle演示在这里: https ://jsfiddle.net/xgya3mzh/2/

EDIT: (it seems like more explanation are required) 编辑:(似乎需要更多说明)

First : the { get property() {} } syntax is from ES5 and you can find doc on MDN here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get 首先: { get property() {} }语法来自ES5,您可以在以下位置找到有关MDN的文档: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

You could accomplish the same with ES3 with another syntax, explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/ defineGetter (but use this syntax only if you wish to support IE8 and below - I hope you don't have to). 您可以使用其他语法在ES3上完成相同的操作,在此处进行解释: https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/ defineGetter (但仅在需要时使用此语法)以支持IE8及以下版本-我希望您不必这样做)。

At #A you declare the variable widget_controller and set it to an (almost) empty object ( {} ); #A您声明变量widget_controller并将其设置为(几乎)空对象( {} ); (I say almost because it still has a prototype with some inherited methods and properties). (我说这几乎是因为它仍然具有一些继承了方法和属性的原型)。

At #C you set the property widget_controller of an object literal (which will be returned by the closure) to the reference of the empty object. #C ,将对象文字的属性widget_controller (将由闭包返回)设置为空对象的引用。

At #B , which happens after #C , you redefine widget_controller of the closure, but you don't redefine the widget_controller of the object returned by the function, which still references the value of the empty object. #B (发生 #C 之后) ,您需要重新定义闭包的widget_controller,但是您不必重新定义该函数返回的对象的widget_controller,该函数仍引用空对象的值。

In my code, in #D , the same widget_controller of the closure is returned whenever you access the property widget_controller of the object returned by the closure. 在我的代码中,在#D ,每当您访问闭包返回的对象的属性widget_controller时,都返回闭包的相同widget_controller。

I hope it is clearer, though I am not very sure... 我希望情况更清楚,尽管我不太确定...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM