Javascript API:范围之外的函数

时间:2014-07-08 08:10:11

标签: javascript jquery

我收到以下错误:未定义SyncNavigationSetCssToState

$(function () {
    var NavigationSetApi = {
        SyncNavigationSetCssToState: function (navigationSet) {
            var navigationSetContent = navigationSet.find(".navigation-set-content");
            var navigationSetHeaderButton = navigationSet.find(".navigation-set-header-button");

            if (navigationSetContent.is(":visible"))
                navigationSetHeaderButton.removeClass("closed").addClass("open");
            else
                navigationSetHeaderButton.removeClass("open").addClass("closed");
        },

        GetAllNavigationSets: function () {
            return $(".navigation-set");
        },

        SyncAllNavigationSetCssToState: function () {
            this.GetAllNavigationSets().each(function () {
                SyncNavigationSetCssToState($(this));
            });
        }
    }

    NavigationSetApi.SyncAllNavigationSetCssToState();
}

我无法理解如何从SyncNavigationSetCssToState中的each()函数中访问SyncNavigationSetCssToState。我怎样才能从这里引用主api对象?

2 个答案:

答案 0 :(得分:5)

您在致电this

时引用SyncNavigationSetCssToState

将来电替换为NavigationSetApi.SyncNavigationSetCssToState

$(function () {
    var NavigationSetApi = {
        SyncNavigationSetCssToState: function (navigationSet) {
            var navigationSetContent = navigationSet.find(".navigation-set-content");
            var navigationSetHeaderButton = navigationSet.find(".navigation-set-header-button");

            if (navigationSetContent.is(":visible"))
                navigationSetHeaderButton.removeClass("closed").addClass("open");
            else
                navigationSetHeaderButton.removeClass("open").addClass("closed");
        },

        GetAllNavigationSets: function () {
            return $(".navigation-set");
        },

        SyncAllNavigationSetCssToState: function () {
            this.GetAllNavigationSets().each(function () {
                NavigationSetApi.SyncNavigationSetCssToState($(this));
            });
        }
    }

    NavigationSetApi.SyncAllNavigationSetCssToState();
}

扩展关于实例的评论......

上面只是一个简单的Javascript对象。 this引用对象NavigationSetApi以保持简单。但是,当您致电this.GetAllNavigationSets().each时,each现在正使用Function.prototype.call设置this

如果您使用NavigationSetApi作为实例,首先需要将其作为一个函数(如果您知道任何OO语言都会想到一个类)

这就是你如何定义它:

function NavigationSetApi(){

}

NavigationSetApi.prototype = {
    SyncNavigationSetCssToState: function (navigationSet) {
        var navigationSetContent = navigationSet.find(".navigation-set-content");
        var navigationSetHeaderButton = navigationSet.find(".navigation-set-header-button");

        if (navigationSetContent.is(":visible"))
            navigationSetHeaderButton.removeClass("closed").addClass("open");
        else
            navigationSetHeaderButton.removeClass("open").addClass("closed");
    },

    GetAllNavigationSets: function () {
        return $(".navigation-set");
    },

    SyncAllNavigationSetCssToState: function () {
        //From Blake Simpson's answer
        var api = this;
        this.GetAllNavigationSets().each(function () {
            api.SyncNavigationSetCssToState($(this));
        });
    }
};

然后调用它你会使用

var instanceApi = new NavigationSetApi();
instanceApi.SyncAllNavigationSetCssToState();

在这种情况下,您正在设置对象的原型,然后在使用new

创建对象时将其“应用”到实例

有趣的是,您还可以在大多数事物的原型中添加内容,例如字符串或日期

示例:

String.prototype.logAWord = function(word){
    console.log(word);
};

// "" is an instance of String
// Logs "Hello"
"".logAWord("Hello");

答案 1 :(得分:1)

可以使用bind来保持this的正确状态并通过参数访问节点:

SyncAllNavigationSetCssToState: function () {
    this.GetAllNavigationSets().each(function (i,node) {
        this.SyncNavigationSetCssToState($(node));
    }.bind(this));
}

但是简单地访问NavigationSetApi变量更容易(而且我相信也更便宜)。