2

私はJSの初心者ですが、この件について調査を行ったところ、網羅的な答えは見つかりませんでした。

プロジェクトに Angular JS を使用しており、いくつかの機能を公開するサービスがあります。

var app = angular.module('myApp', [])

app.service('mySrv', function() {

    this.myFoo = function() {
        var anObject = {}
        //some code on the object...
        return anObject
    }

    this.myGoo = function() { // function(object) maybe?
        //some code on an object again
        return aNewObject
    }
}

次に、コントローラーで JQuery のようなことを行い、myFoo の出力を myGoo の入力としてチェーンします。

$scope.myObj = mySrv.myFoo(['some','params']).myGoo('another_one')

ここで述べたように、チェーン機能を追加するためにプロトタイプ プロパティを使用できることがわかりました JavaScript でチェーン機能を作成する方法は? しかし、同じ答えは、オブジェクトで行うべきではないと言っています。これは私の場合です...

最後になりましたが、JavaScript Object Method Chaining という別の方法があります: 便利ですか?
率直に言って、私は理解できませんでした...

誰かが私の心からこの霧をすべて取り除くことができますか?


編集: @plalx と @Connor の優れた例を使用して混合することで、このスニペットを機能させることができました。ご覧のとおり、@plalx の例の「連鎖可能な部分」がありません。

その部分は正確に何をしますか?

var o = {
    setTest: function (test) {
        this.test = test;
        return this
    },
    getTest: function () {
        this.test = this.test.toUpperCase()
        return this
    },
    splitMe: function() {
        return this.test.split('')
    }
};

console.log( o.setTest('hello').getTest().splitMe() )
4

2 に答える 2

1

オブジェクト メソッドを動的に連鎖可能にする方法の例を次に示します。

を呼び出すchainable(obj)と、 と同じ API を公開する新しいオブジェクトが内部的に作成されますがobj、すべての関数がその新しいオブジェクトを返すようになり、連鎖が可能になります。関数を呼び出してその関数の生の結果を取得したい場合は、 を呼び出すことができますendChain()

次の実装は、 のすべてのメンバーをループする必要があるため、あまり効率的ではありませんobjより良いアプローチは、チェーン可能にしたい関数から現在のインスタンス ( ) を返すことによって、メソッドをチェーン可能にすることです。this

デモ

var chainable = (function () {

    function wrapFn(fn, obj) {
        return function () {
            var result = this._result = fn.apply(obj, arguments);

            return this;
        };
    }

    function Chainable(obj) {
        var k, v;

        for (k in obj) {
            if (typeof (v = obj[k]) !== 'function') continue;

            this[k] = wrapFn(obj[k], obj);
        }
    }

    Chainable.prototype.endChain = function () {
        return this._result;
    };

    return function (obj) {
        return new Chainable(obj);
    };

})();

var o = {
    setTest: function (test) {
        this.test = test;
    },
    getTest: function () {
        return this.test;
    }
};

console.log(chainable(o).setTest('test').getTest().endChain());

オブジェクト メンバーを反復処理する必要のない別の実装を次に示します。ただし、構文的にはあまり魅力的ではなく、slice引数が必要なため、より効率的かどうかはわかりません。

デモ

var chainable = (function (slice) {
    var Chainable = {
        init: function (obj) {
            this._obj = obj;

            return this;
        },

        chain: function (fn) {
            var obj = this._obj;

            this._result = obj[fn].apply(obj, slice.call(arguments, 1));

            return this;
        },

        end: function () {
            return this._result;
        }
    };

    return function (obj) {
        return Object.create(Chainable).init(obj);
    };
})(Array.prototype.slice);

var o = {
    setTest: function (test) {
        this.test = test;
    },
    getTest: function () {
        return this.test;
    }
};

console.log(chainable(o).chain('setTest', 'test').chain('getTest').end());

編集:

@plalx と @Connor の優れた例を使用して混合することで、このスニペットを機能させることができました。ご覧のとおり、@plalx の例の「連鎖可能な部分」がありません。

chainableコードが連鎖可能な方法で既に記述されている場合 (たとえばthis、いくつかの関数から既に返されている場合)のようなものは必要ありません。もっと分かりやすくするべきだった。chainableチェーンがどのように機能するかの例として実装を書きました。

ただし、明示的に を返す関数がない場合でも、任意のオブジェクトを連鎖chainable可能にすることができます。API を介してチェーンをサポートしていないオブジェクトでチェーンを使用する場合に役立ちます。this

例えば

var o = {
    fn1: function () { console.log('fn1'); },
    fn2: function () { console.log('fn2'); }
};

//chainable(o).fn1().fn2(); //other implementation

chainable(o).chain('fn1').chain('fn2');

これは、オブジェクトを動的に連鎖可能にすることがパフォーマンスに大きな悪影響を与えることを示すパフォーマンステストです。そのため、その実験的なアプローチを使用することはお勧めしません。

于 2013-10-21T23:17:18.887 に答える
1

return this;そのように使用する必要があります。

app.service('mySrv', function() {

    this.myFoo = function() {
        var anObject = {}
        //some code on the object...
        return this;
    }

    this.myGoo = function() { // function(object) maybe?
        //some code on an object again
        return this;
    }
}

とにかく使用できないため、連鎖可能な場合は何も返すべきではありません。jQuery のすべてと同様にoffset();、連鎖できないものもあります。

于 2013-10-21T22:31:19.883 に答える