Javascript变量在一个函数中设置,但在另一个函数中未定义

时间:2015-06-10 21:40:08

标签: javascript jquery namespaces scope

我有以下Javascript,

eventManager: {
    $musicGenres : null, // $musicGenres is the selector for a div-container of inputs
    musicGenres : [],

    // Functions
    handle : function(selectors) {
        selectors = (typeof selectors === 'undefined') ? {
            'musicGenres' : '#musicGenres'
        } : selectors; // selectors default values...
        this.$musicGenres = $(selectors['musicGenres']);
        console.log("CHANGED $musicGenres TO " + this.$musicGenres);

        this.$musicGenres.find('input').change(this.reloadMusicGenres);
    },
    reloadMusicGenres : function() {
        console.log("IN FUNCTION $musicGenres IS " + this.$musicGenres);
    },

,在我的页面上调用函数eventManager.handle()并触发其中一个输入的更改事件,输出

CHANGED $musicGenres TO [object Object]
IN FUNCTION $musicGenres IS undefined

我不明白的。我已将$ musicGenres设置为新值,但在reloadMusicGenres函数中,它保持未定义状态。即使我手动访问$ musicGenres'通过键入eventManager.$musicGenres输入正确的值,通过控制台输入值。

有人能帮帮我吗?这真让我担心。

4 个答案:

答案 0 :(得分:2)

您是否尝试过使用handle方法:

var self = this;
this.$musicGenres.find('input').change(function () {      
     self.reloadMusicGenres();
});

调用reloadMusicGenres函数时,可能是一个范围问题。

答案 1 :(得分:2)

正如其他人已经指出的那样,你的问题是上下文绑定。

IMO修复代码的最简单方法是更改​​此行

this.$musicGenres.find('input').change(this.reloadMusicGenres);

到此:

this.$musicGenres.find('input').change(this.reloadMusicGenres.bind(this));

这应该可以解决您的问题。无需更改代码中的任何其他内容。

答案 2 :(得分:2)

context的{​​{1}}已发生变化。解决此问题的最简单方法是在函数外部引用this,或传递this对象(如其他两个精美海报,Richard Healy和AlliterativeAlice所建议的那样)。

第三种方式是明确data bind的背景。使用jQuery,您可以通过调用this来实现此目的。所以,这个:

$.proxy

变为:

this.$musicGenres.find('input').change(this.reloadMusicGenres);

this.$musicGenres.find('input').change($.proxy(this.reloadMusicGenres, this)); 将返回一个新函数,其中$.proxy将始终绑定到this。如果您对退出jQuery感兴趣,eventManager就是您的答案(编辑:Zoltan提供的一个例子)

以下是有关如何使用这些优良功能的文档的链接:

jQuery代理:https://api.jquery.com/jQuery.proxy/

绑定功能:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

答案 3 :(得分:1)

您可以将对象传递给更改处理程序,如下所示:

this.$musicGenres.find('input').change(this, this.reloadMusicGenres);

然后在reloadMusicGenres()

reloadMusicGenres : function(e) {
    console.log("IN FUNCTION $musicGenres IS " + e.data.$musicGenres);
}