0

パブリック メンバーとプライベート メンバーを許可する次の形式の名前空間があります。

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: 異なるファイルから)。

ここに JSFiddle があります。

4

3 に答える 3

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繰り返しますが...元のコードで変数の前に置くことを忘れないでください。

于 2013-02-17T02:46:16.167 に答える
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>

同じ「名前空間」(またはオブジェクトとしましょう) の下で 2 つの異なる 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
        }
    }
};
于 2013-02-17T02:51:26.277 に答える
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その「パブリック」オブジェクトを返す変数は、「プライベート」データと対話するメソッドを呼び出すことができますが、メソッドを介してアクセスしたり変更したりすることはできませんしかし、それらの「公開」機能を使用するには。

これを 8 層の深さでネストし、IIFE を使用して、先ほど説明したのとまったく同じ閉鎖の概念を使用します。

何を返すか、何を返さないかを明示的に決定します。
あなたが世界に送る機能はpublic. 返されなかったりオブジェクトにアタッチされていない、関数内の関数などは非公開です。
それらは、返された「コンストラクター」関数によって閉じられており、プライベート変数を参照し、パブリックメソッドとして返された、コンストラクター内で構築された関数を使用する場合を除いて、現在は 100% アクセスできません。

于 2013-02-17T03:33:10.520 に答える