10

モジュール パターンを使用せずに、呼び出し可能なクラスのインスタンス化を複製したいと考えています。

以下は、これに対する私の最善の試みです。しかし、それは__proto__私がよくわからないものを使用しています。これはなしで行うことができます__proto__か?

function classcallable(cls) {
    /*
     * Replicate the __call__ magic method of python and let class instances
     * be callable.
     */
    var new_cls = function () {
        var obj = Object.create(cls.prototype);
        // create callable
        // we use func.__call__ because call might be defined in
        // init which hasn't been called yet.
        var func = function () {
            return func.__call__.apply(func, arguments);
        };
        func.__proto__ = obj;
        // apply init late so it is bound to func and not cls
        cls.apply(func, arguments);
        return func;
    }
    new_cls.prototype = cls.prototype;
    return new_cls

}
4

1 に答える 1

7

プロキシー

またはそれに関連するものを使用することに反対し__proto__ているが、それでも継承可能性が必要な場合は、Proxiesを利用できます。

var ObjectCallable_handler = {
    get: function get(self, key) {
        if (self.hasOwnProperty(key)) {
            return self[key];
        } else { return self.__inherit__[key]; }
    },
    apply: function apply(self, thisValue, args) {
        return (self.__call__ || self.__inherit__.__call__).apply(self, args);
    }
};

function ObjectCallable(cls) {
    var p = new Proxy(function() { }, ObjectCallable_handler);
    p.__inherit__ = cls;
    return p;
}

長所

  • 継承性を維持します。
  • 従来のプロトタイプ チェーンを必要としません。
  • ES6 ドラフト

短所


setPrototypeOf

プロキシがサポートされていないことにがっかりする場合は、代わりにポリフィルを試すことができますsetPrototypeOf

Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
    obj.__proto__ = proto;
    return obj;
}

function ObjectCallable(cls) {
    var f = function() { return f.__call__.apply(f, arguments); };
    Object.setPrototypeOf(f, cls);
    return f;
}

長所

  • 現在も将来も最高のパフォーマンスを発揮する可能性があります。
  • ES6 ドラフト

短所

  • __proto__ポリフィルを介して非標準を利用するため、サポートするエンジン/ブラウザー全体でテストする必要があります。
  • setPrototypeOf現在、どのブラウザーにも実装されていません

コピー

これは最小限の機能しか持たない最も単純なソリューションですが、ほぼどこでも機能することが保証されています。新しい関数を作成し、オブジェクトのプロパティを複製します。

function ObjectCallable(cls) {
    var f = function() { return f.__call__.apply(f, arguments); }, k;
    for (k in cls) {
        f[k] = cls[k];
    }
    return f;
}

長所

  • 事実上どこでも機能します。

短所

  • 継承またはプロトタイプ構造の類似性をまったく維持しません。

結論

JavaScript でPython の機能を複製することでやりたいことは__call__、ES6 が開発されてより多くのエンジンで実装されるようになるにつれて、より多くの時間が必要になるか、__proto__.

于 2013-11-16T18:50:00.970 に答える