为什么不按我希望的那样工作?

问题描述:

我写了这段代码,希望运行后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(); 
}); 
+0

您的onDocumentReady()函数没有被调用?那是怎么回事? –

+0

在尝试将widget_date_range属性写入它之前,search_form是否有值? 这可能是变量提升的标志。你准备好的函数中的任何地方是否声明“var search_form”? –

+0

@Marcos。感谢马科斯,是的,我从底部的document.ready中调用它。 –

我认为你缺少一个关于参考点在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找到DOC: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。

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

+1

我的天啊,它的作品!我的版本有什么问题,亲爱的拉鲁伊斯?它不是一个典型的闭包,我的onDocumentReady函数中的widget_controller应该引用它的直接外部作用域,它将widget_controller定义为一个空对象{}?为什么必须重新定义它?我现在正在挠头。 –

+1

另外,你能否提供关于如何“获取widget_controller()”部分的线索?我试着用Google搜索,但没有找到任何相关的东西。非常感谢。 –

+0

有人能解释一下为什么我的第一个版本不起作用的一点线索吗?这对我来说似乎是一个完美的封闭。非常感谢。 –