如何附加到从闭包创建的JavaScript命名空间?

时间:2013-02-17 02:15:10

标签: javascript namespaces javascript-namespaces

我有以下格式的命名空间,允许公共和私人成员:

function A() {
    return('a');
}

namespace1 = (function () {
    // private
    namespace2 = (function() {
        // private
        prC = function () {
            return(namespace1.puB() + 'c');
        };
        puC = function () {
            return(prC());
        };
        // public
        return({
            puC: puC
        });
    })();
    prB = function () {
        return(A() + 'b');
    };
    puB = function () {
        return(prB());
    };
    // public
    return({
        puB: puB,
        namespace2: namespace2
    });
})();

document.write('A() = '); try {  document.write(A()); } catch (ex) { document.write('inaccessible'); }
document.write('<BR />');
document.write('namespace1.prB() = '); try {  document.write(namespace1.prB()); } catch (ex) { document.write('inaccessible'); }
document.write('<BR />');
document.write('namespace1.puB() = '); try {  document.write(namespace1.puB()); } catch (ex) { document.write('inaccessible'); }
document.write('<BR />');
document.write('namespace1.namespace2.prC() = '); try {  document.write(namespace1.namespace2.prC()); } catch (ex) { document.write('inaccessible'); }
document.write('<BR />');
document.write('namespace1.namespace2.puC() = '); try {  document.write(namespace1.namespace2.puC()); } catch (ex) { document.write('inaccessible'); }

输出:

A() = a
namespace1.prB() = inaccessible
namespace1.puB() = ab
namespace1.namespace2.prC() = inaccessible
namespace1.namespace2.puC() = abc

我如何将公共成员和私有成员附加到这样的命名空间(IE:来自不同的文件)?

Here's a JSFiddle

3 个答案:

答案 0 :(得分:2)

  

“我如何将公共和私人成员附加到这样的命名空间......”

好吧,您的函数已暴露,因为您没有使用var正确声明变量。

但是一旦你解决了这个问题,你可以从任何可以引用你的namespace对象的代码中添加更多公开的属性(因为所有属性都公开了)


添加更多引用本地(私有的正确术语)函数的属性,您需要一个新函数和变量范围。

只需调用引用namespace对象的函数,在该函数内创建一些函数,并添加引用这些局部函数的属性。

// Other file

(function() {
    var newLocalFunc = function() {
        // local function
    }

    var anotherLocalFunc = function() {
        // local function
    }

    namespace1.exposedFunc = function() {
        return newLocalFunc()
    }
    namespace1.namespace2.anotherExposedFunc = function() {
        return anotherLocalFunc()
    }
})();

再次......不要忘记将var放在原始代码中的变量之前。

答案 1 :(得分:1)

未使用 var 关键字声明的任何变量都将位于全局范围中。因此,puB()函数不是不可访问的或私有的,它不是namespace1函数返回的对象的成员。例如,尝试使用window.prB(),您会看到该方法存在于window对象的全局范围内。

<head>
    <script type="text/javascript">
        obj1 = {}; //in global scope
        var obj2 = {}; //in global scope. Although used the var keyword, this line itself is in the global scope; so the variable.
        function someFunc() {
            obj3 = {}; //in global scope
            var obj4 = {}; //'so-called' private (inaccessible from global scope)
        }
    </script>
</head>

用于在同一个“命名空间”(或者说对象)下组合两个不同的JS文件:

文件-1 的.js

var namespace1 = (function() {
    // some code...
    var namespace2 = (function() {
        // some code...
        return {
            obj2: 'value2'
        };
    })();

    return {
        obj1: 'value1'
    };
})();

文件-2 的.js

namespace1.namespace3 = (function() {
    // some code...
    var ns4 = (function() {
        // some code...
        return {
            obj4: 'value4'
        };
    })();

    return {
        obj3: 'value3',
        namespace4: ns4
    };
})();

什么是:

  • namespace1在全局范围内声明;所以它是可访问的 来自任何地方,这是我们的主要目标。
  • namespace2无法访问(私有)。
  • namespace3在全局范围内无法访问,但可以作为 namespace1的成员;例如:namespace1.namespace3
  • namespace4可以namespace1的成员身份访问。例如。: namespace1.namespace4

因此;我们的主要对象 namespace1 的成员是:

namespace1 = {
    obj1: String,
    namespace3: {
        obj3: String,
        namespace4: {
            obj4: String
        }
    }
};

答案 2 :(得分:0)

离这里堪萨斯州很远。

你不能“公开”公开或私人的东西 只要你在函数内部定义东西,然后选择返回特定的东西,或者将它们附加到你作为参数传入的对象/数组中,那么你将拥有对这些东西的“公共”(外部)访问权限。函数返回。

为了获得“私人”访问权限,您将返回一个引用内部内容的函数。

var Wallet = function (amount, overdraft_limit) {
    var balance = 0,
        overdraft = overdraft_limit || 0,

        deposit_funds = function (funds) { balance += funds; return true; },

        withdraw_funds  = function (request) {
            var funds = 0;
            balance -= request;
            funds = request;
            return funds;
        },

        validate_request = function (pin) { /* ... */ },

        sufficient_funds = function (val) { return val <= (balance + overdraft); },

        add = function (pin, deposit) {
            if (!validate_request(pin) || deposit <= 0) { return false; }

            var result = deposit_funds(deposit);
            return result;
        },

        deduct = function (pin, withdrawl) {
            if (!validate_request(pin) || withdrawl <= 0) { return false; }
            if (!sufficient_funds(withdrawl)) { return false; }

            var funds = withdraw_funds(withdrawl);
            return funds;
        },

        check = function () { return balance; },

        public_interface = { deduct : deduct, add : add, check : check };

    return public_interface;
};


var myWallet = Wallet(30, 20);

var cash = myWallet.deduct(40);
cash;             //  40
myWallet.check(); // -10

myWallet.balance = 40000000000;

cash = myWallet.deduct(4000);
cash;  // === false

通过在我的“构造函数”中构建可以访问balance的函数,我返回的那个“public”对象的变量可以调用方法来与“私有”数据进行交互,但是不能访问它或通过任何方法修改它,但使用那些“公共”功能。

将这些东西嵌套8层深,使用IIFE使用完全相同的闭合概念,我刚刚演示过。

明确决定你将要归还的内容以及你不会返回的内容 您发送到世界的功能是public。函数内部未返回或附加到对象的函数/ etc是私有的 它们已被关闭的“构造函数”函数关闭,现在它们100%无法访问,除非使用构造函数内部构建的函数,这些函数引用私有变量,并作为公共方法返回。 / p>