是否可以在javascript函数中将namespace作为参数传递?

时间:2014-02-10 06:45:25

标签: javascript jquery javascript-namespaces

我有3个.js文件。主要的Home.js和另外两个.js文件,例如Page1.js,Page2.js

Home.js:

 var Home= {

            Sample: function (pageId,data) {

            pageId.MergePageData(data);
        }
    }

Page1.js:

var Page1 = {

    MergePageData: function (data) {
    // do something
   }
}

Page2.js:

var Page2 = {

    MergePageData: function (data) {
     // do something
   }
}

我尝试通过将其作为字符串传递来调用:

Home.Sample('Page1', 'data');

Home.Sample('Page2', 'data');

但我想因为它正在以字符串形式传递错误

“对象不支持属性或方法'MergePageData'”

我需要在两个不同的js文件中区分两个函数之间的调用。如何实现?

2 个答案:

答案 0 :(得分:1)

你的函数中的pageId只是一个变量,当你调用它时,你指定这个变量的类型,当你传递"Page1"时,它是String它是只是一个字符串,与您的真实Page1对象没有任何关系。但有一些选项可以帮助你。

您必须考虑的另一点是,您有2个或3个不同的js文件并不重要。重要的一点是,如果您的所有JavaScript代码都被注入单个html页面,那么您可以将所有JavaScript代码中的所有代码放在单window个上下文中。因此,如果您在window的全局范围内定义某些内容,则可以通过JavaScript代码访问它。

您的Page1Page2似乎是全局对象,因此您可以这样做:

var Home= {

        Sample: function (pageId,data) {

        window[pageId].MergePageData(data);
    }
}

但我猜data vriable不是全球性的,你有2个选项,首先将它设为全局或者只是将它存储在如下存储中:

localStorage.setItem("data", JSON.stringify(data));

然后更改您的Sample功能:

var Home= {

        Sample: function (pageId,data) {

        window[pageId].MergePageData(JSON.parse(localStorage.getItem("data")));
    }
}

虽然您必须非常小心data对象的大小,但如果它是具有大量属性和内部对象的大对象,则应重新考虑并更改解决方案。

答案 1 :(得分:1)

基本上您想在IIFE内创建对象Home。这样,您可以在几个文件中传入任何库或对象命名空间。

对于Home对象,声明并运行匿名函数,将对象直接分配给window对象。这将是您的“命名空间”,可通过window.Home在整个文件中访问。使用此文件初始化Page对象。至于现在,DOM ready事件是从jQuery使用的。

// @param ($): jquery library 1.10.2
(function ($) {

    // 1. ECMA-262/5
    'use strict';

    // 2. PRIVATE CONFIGURATION
    var cfg = {
        // an object literal to store config
        page2: {
            page: 'page2',
            data: 'data'
        }
    };

    // 3. GLOBAL OBJECT NAMESPACE
    window.Home = {
        init: function(){
            // initialize your other files
            this.cache = {
                page1: new Home.Sample();
                page2: new Home.Sample(cfg.page2); 
            }
        }
    };

    // 4. ONCE THE DOM IS READY
    $(function () {
        Home.init();
    });

}(window.jQuery));

然后,对于其他文件,可以使用稍微不同的方法。

// @param ($): jquery library 1.10.2
// @param (home): Home namespace
window.Home = (function ($, home) {

    // 1. ECMA-262/5
    'use strict';

    // 2. CONFIGURATION
    var cfg = {
        page: 'page1'
        data: 'data'
    };

    // 3. CONSTRUCTOR FUNCTION
    home.Sample = function (options) {
        this.settings = $.extend({}, cfg, options);
        this.init();
    };

    // 4. PROTOTYPE OBJECT
    home.Sample.prototype = {
        init: function(){
            this.cacheItems();
            this.mergePageData(settings.data);
        },

        cacheItems: function(){
            this.page = settings.page;
        },

        mergePageData: function (data) {
            // do something with this.page and data
            // consider caching data instead of passing it along
        }
    };

    // 5. GLOBALIZE OBJECT
    return home;

}(window.jQuery, window.Home || {}));

这种方法是模块化的,更好地维护。由于整个配置是从逻辑中提取的,因此您会发现创建对象的不同实例更容易。只需将options传入您的Sample对象,您就可以更改整个数据/结构,但保持行为符合预期。您可以从服务器语言填写选项,并在jQuery todo强大的DOM遍历中使用sizzle选择器引擎,等等......