2

これは少し変わったように聞こえるかもしれません。これまでこのように角括弧表記を使用する必要はありませんでした。頭を悩ませて、望ましい結果を生み出す方法を考えることはできません。

thisメソッドをコールバックとして渡すときの参照を維持するために、コールバックラッパーを実装しています

例えば

foo.prototype.wrap = function(name){
    var wrapper,
        self = this;

    wrapper = function(){
        self[name](arguments);
    };

    return wrapper;
};

// usage

foo.wrap('bar');

// executes foo.bar maintaining 'this' as a reference to foo 

私が抱えている問題は、fooにいくつかのネストされたメソッドがあることです

例えば

foo.bar.close();

wrapメソッドがネストされたメソッドをサポートするようにする方法を見つけようとしています

例えば

foo.wrap('bar.close')

// or

foo.wrap('bar','close');

したがって、foo.wrap関数は、渡された長さまたは引数に対応する角かっこを動的に追加する必要があります。

例えば

self[x][y][z](arguments);

私はこれを行う方法を考えることができません。何か案は ?

私はこれが不可能であるというこっそりの疑いを持っています。

4

2 に答える 2

6

私はあなたがすべてを忘れる日を過ごしているに違いありません:)

@NilColorの答えは正しいですが、私はそれを知っていましたが、正しい帽子をかぶって考えていませんでした。

とにかく、オブジェクトにアタッチするときに必要な特定性が少し低いラッパーを使用するというアイデアがまだ好きだと判断しました。そして、少し冗長です。

ということで、オリジナルの考え方で書いてみましたので、気に入っていただけると幸いです。

myObj.wrap = function(path, context){ 
    var wrapper,
        method = ( typeof path != 'string' && context )? path : this,
        context =  (typeof path === 'object' && context === undefined)? 
            path : (context || this);

    if (typeof path === 'string'){
        path = path.split('.');

        for ( var i = 0; i < path.length; i++ ){
            method = method[path[i]];
            if ( context === true  )
                context = ( i === path.length - 2 )? method : context; 
        };
    };

    wrapper = function(){
        method.apply(context, arguments);
    };

    return wrapper;
}

利用方法:

ネストされたメソッドをいくつでも myObj にバインドします

    myObj.wrap('foo') //binds myObj.foo to myObj

// or

    myObj.wrap('foo.bar') //binds myObj.foo.bar to myObj

//or if myObj is a function

    myFunc.wrap() // binds myFunc to myFunc

myObj のメソッドを別のオブジェクトにバインドする

    myObj.wrap('foo.bar', someObj) //binds myObj.foo.bar to someObj

//or if myObj is a function

    myFunc.wrap(someObj) //Binds myFunc to someObj

ネストされたメソッドをその親にバインドします

    myObj.wrap('foo.bar', true) // binds myObj.foo.bar to myObj.foo

助っ人として使う

    myObj.wrap(someFunc, someObj) //binds someFunc to someObj

メソッドバインディングのコンテキストではなく、元の質問への回答を探している場合。

myObj.getProps = function(path, context){
var context = context || this;
    path = path.split('.');


for ( var i = 0; i < path.length; i++ ){
            context = context[path[i]];
    };

    return context;
};

使用法:

オブジェクトにアタッチするか、スタンドアロン関数として

プロパティを取得する

myObj.getProps('foo.bar') // returns mayObj.foo.bar

コンテキストオブジェクトを与える

myObj.getProps('user.name', myAccounts) // returns myAccounts.user.name

スタンドアロン関数として使用するには

myObj.getProps = function(path,context){....}

function getProps(path,context){....}

ノート

スタンドアロン関数として使用する場合は、 のスコープから検索を開始することを覚えておく必要がありますthis。したがって、グローバル スコープで定義されている場合は、フル パスを指定する必要があります。

例えば

getProps('myObj.foo.bar')

コンテキスト セレクターを使用して参照オブジェクトを変更することもできます。

于 2011-08-22T22:37:18.133 に答える
3

「バインディング」の一般的な概念thisは次のようなものです。

function bind(method, context) {
      var args = Array.prototype.slice.call(arguments, 2);
      return function() {
            var a = args.concat(
                               Array.prototype.slice.call(arguments, 0));
            return method.apply(context, a);
      }
}

このようにしてmethod、リンクされたthis( context) への参照を取得します。このようにして、ネストされたメソッドを次のようにバインドできます。

> foo = {}
> foo.a = function(){console.log('a'); console.log(this)}
> bar = {bar: 'yeah'}
> f = bind(foo.a, bar)
> f()
-> a
-> {bar: 'yeah', __proto__: Object}

それはあなたが探しているものですか?

于 2011-08-22T11:50:42.500 に答える