7

たとえば、次のようなオブジェクトがあります。

obj = {
    subobj1: {

    },
    subobj2: {
        func1: function(){

        },
        func2: function(){

        }
    },
    subobj3: {
        func3: function(){

        },
        func4: function(){

        }        
    },
}

obj.subobj2.func1()を呼び出さずに、func4内からfunc1を呼び出すにはどうすればよいですか?

4

7 に答える 7

15

正確にはできません。関数がどのオブジェクトに存在するかを知る意味はありません。

複数の場合があることに注意してください:既存のコードの後に​​これを記述できた可能性があります:

var obj2 = {some:obj.subobj3};

したがって、プロパティ値からそれを保持するオブジェクトへの一意のリンクは存在できません(アクセス可能なリンクはありません)。

ここで、オブジェクトの作成時に作成されたリンクに満足すると仮定すると、ファクトリを使用してオブジェクトを構築できます。

obj = (function(){
    var parent = {
        subobj1: {

        },
        subobj2: {
            func1: function(){

            },
            func2: function(){

            }
        },
        subobj3: {
            func3: function(){

            },
            func4: function(){
                parent.subobj2.func1();
            }        
        }
    };
    return parent;
})();

その後、あなたは呼び出すことができます

obj.subobj3.func4();

デモンストレーション


編集

質問にタグOOPを付けたようです。私が与えたパターンは、モジュールを定義するためにより頻繁に使用されることを知っておく必要があります。javascriptのOOPは、インスタンス共有メソッドと継承を有効にするために、newとを使用して行われることがよくあります。prototypeおそらくOOPではなくモジュールが必要なので、問題はないようです。

この紹介を参照してください。

于 2012-11-23T18:24:13.520 に答える
1

ファイルシステムの「..」のようにオブジェクト階層を「上に移動」する方法がないため、これを直接行うことはできません。

できることは、サブオブジェクトまたはサブ関数を直接指す変数を用意することです。これにより、それらを呼び出すために階層を通過する必要がなくなります。以下は、Javascriptモジュールを作成するための一般的なパターンです。

obj = (function(){

    var obj1 = {...}
    var obj2 = {...}

    var func3 = function(){...};
    var func4 = function(){...};

    return {
        subobj1: obj1,
        subobj2: obj2,
        subobj3: {
            func3: func3,
            func4: func4
        }
    }
}());

この例では、内部関数は、、、obj1およびそれらobj2の変数から直接アクセスできます。自己呼び出し関数は、これらの内部変数がプライベートで外部から隠されているようにし、returnステートメントを使用すると、パブリックにしたい関数のみをエクスポートできます。func3func4

于 2012-11-23T18:36:46.407 に答える
1

他の人が言ったように、単純なオブジェクトでは、ネストされた子から親を検索することはできません。

ただし、再帰的なES6 プロキシをヘルパーとして使用する場合は可能です。

ObservableSlimという名前のライブラリを作成しました。これにより、子オブジェクトから親オブジェクトまでトラバースできるようになります。

簡単な例を次に示します ( jsFiddle demo )。

var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function(changes) {
    console.log(JSON.stringify(changes));
});

function traverseUp(childObj) {
    console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}}
    console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object
};

traverseUp(proxy.hello.foo);
于 2018-01-25T08:18:28.063 に答える
0

それは不可能です。オブジェクトプロパティは、それらが設定されているオブジェクトによって取得されます。obj.subobj2.func1JavaScriptは、ルートオブジェクトを暗黙的にグローバルとして設定しないため、エイリアスを変更することはできませんfunc1。その関数を過度に呼び出していることに気付いた場合は、代わりに変数を設定してみてください。

于 2012-11-23T18:36:19.063 に答える
0

これは、よりActionScript似ていて理解しやすい回答です。

function MainObject() {
   this.x = 100;
   this.y = 50;
   this.second = new SecondObject(this);
}

function SecondObject(p) {
    this.parent = p;
}

var firstobject = new MainObject();

// Saving a reference to SecondObject.
var secondObject = firstobject.second;

// Because of parent variable, you can access second object parent without needing to have the parent object in a variable.
console.log(secondObject.parent.x);
console.log(secondObject.parent.y);

オブジェクトは複数の親を持つことができないことに注意してください。

于 2013-07-03T16:06:04.833 に答える