JavaScript関数を継承するにはどうすればよいですか?

レイノス:
// Don't break the function prototype.
// pd - https://github.com/Raynos/pd
var proto = Object.create(Function.prototype, pd({
  "prop": 42
}));

var f = function() { return "is a function"; };
f.__proto__ = proto;

console.log(f.hasOwnProperty("prop")); // false
console.log(f.prop); // 42
console.log(f()); // "is a function"

.__proto__ 非標準であり、非推奨です。

オブジェクトをプロトタイプ的に作成して継承するが、そのオブジェクトを関数にする方法を教えてください。

Object.create 関数ではなくオブジェクトを返します。

new Constructor 関数ではなくオブジェクトを返します。

動機: -クロスブラウザfinherit

var finherit = function (parent, child) {
    var f = function() { 
        parent.apply(this, arguments);
        child.apply(this, arguments);
    };
    f.__proto__ = parent;
    Object.keys(child).forEach(function _copy(key) {
        f[key] = child[key];
    });
    return f;
};

私はこれが可能であるとは思わないので、おそらくFunction.createes-discussメーリングリストに提案する必要があります

/*
  Creates a new function whose prototype is proto.
  The function body is the same as the function fbody.
  The hash of propertydescriptors props is passed to defineproperties just like
  Object.create does.
*/
Function.create = (function() {
  var functionBody = function _getFunctionBody(f) {
    return f.toString().replace(/.+\{/, "").replace(/\}$/, "");
  };
  var letters = "abcdefghijklmnopqrstuvwxyz".split("");

  return function _create(proto, fbody, props) {
    var parameters = letters.slice(0, fbody.length);
    parameters.push(functionBody(fbody));
    var f = Function.apply(this, parameters);
    f.__proto__ = proto;
    Object.defineProperties(f, props);
    return f;
  };
})();

関連es-discussメール

es-discussスレッド<|で述べたように、これを可能にするES:strawman プロトタイプオペレーターが存在します。

それを使ってどのように見えるか見てみましょう <|

var f1 = function () {
  console.log("do things");
};

f1.method = function() { return 42; };

var f2 = f1 <| function () {
  super();
  console.log("do more things");
}
console.log(f1.isPrototypeOf(f2)); // true
console.log(f2()); // do things do more things
console.log(f2.hasOwnProperty("method")); // false
console.log(f2.method()); // 42
mr.stobbe:

私はこの権利を理解していると思います。

定義済みのプロトタイプのインスタンス(そう、クラスで、クラシッククラスではない)であり、直接呼び出し可能なファンクタが必要だと思いますか?正しい?その場合、これは完全に意味があり、非常に強力で柔軟性があります(特にJavaScriptのような高度に非同期の環境では)。悲しいことに、操作せずにJavaScript エレガントそれを行う方法はありません__proto__これを行うには、無名関数を分解し、すべてのメソッドへの参照をすべてコピーします(これは目的の方向のようです)プロキシクラスとして機能します。これの欠点は...

  1. 実行時間の点で非常にコストがかかります。
  2. (functorObj instanceof MyClass)になることはありませんtrue
  3. プロパティには直接アクセスできません(すべて参照によって割り当てられた場合、これは別の話になりますが、プリミティブは値によって割り当てられます)。これはdefineProperty、必要に応じて、または必要に応じて単に名前の付いたアクセサメソッドでアクセサを使用して解決できます(これが目的のようですが、definePropertyクロスが必要ない場合は、関数だけでなくすべてのプロパティをgetter / setter 介してファンクタに追加します-engineサポート/後方互換性)。
  4. 最終的なネイティブプロトタイプ(Object.prototypeやArray.prototype([継承]している場合)など)が期待どおりに機能しない可能性のあるエッジケースに遭遇する可能性があります。
  5. 呼び出しfunctorObj(someArg)ます常に作りthisコンテキストに関係なく、それが呼ばれていた場合の、オブジェクトであることfunctorObj.call(someOtherObj, someArg)(これは、メソッド呼び出しのためのケースではありませんが)
  6. ファンクターオブジェクトはリクエスト時に作成されるため、時間内にロックされ、初期プロトタイプの操作は、通常のオブジェクトのように割り当てられたファンクターオブジェクトに影響を与えません(MyClass.prototypeの変更はファンクターオブジェクトに影響を与えず、その逆も同様です)同様に)。

しかし、それを穏やかに使用する場合、これはどれも大したことではありません。

クラスのプロトタイプで次のように定義します...

// This is you're emulated "overloaded" call() operator.
MyClass.prototype.execute = function() {
   alert('I have been called like a function but have (semi-)proper access to this!');
};

MyClass.prototype.asFunctor = function(/* templateFunction */) {
   if ((typeof arguments[0] !== 'function') && (typeof this.execute !== 'function'))
      throw new TypeError('You really should define the calling operator for a functor shouldn\'t you?');
   // This is both the resulting functor proxy object as well as the proxy call function
   var res = function() {
      var ret;
      if (res.templateFunction !== null)
         // the this context here could be res.asObject, or res, or whatever your goal is here
         ret = res.templateFunction.call(this, arguments);
      if (typeof res.asObject.execute === 'function')
         ret = res.asObject.execute.apply(res.asObject, arguments);
      return ret;
   };
   res.asObject = this;
   res.templateFunction = (typeof arguments[0] === 'function') ? arguments[0] : null;
   for (var k in this) {
      if (typeof this[k] === 'function') {
         res[k] = (function(reference) {
            var m = function() {
               return m.proxyReference.apply((this === res) ? res.asObject : this, arguments);
            };
            m.proxyReference = reference;
            return m;
         })(this.asObject[k]);
      }
   }
   return res;
};

結果の使用法は次のようになります...

var aobj = new MyClass();
var afunctor = aobj.asFunctor();
aobj.someMethodOfMine(); // << works
afunctor.someMethodOfMine(); // << works exactly like the previous call (including the this context).
afunctor('hello'); // << works by calling aobj.execute('hello');

(aobj instanceof MyClass) // << true
(afunctor instanceof MyClass) // << false
(afunctor.asObject === aobj) // << true

// to bind with a previous function...
var afunctor = (new MyClass()).asFunctor(function() { alert('I am the original call'); });
afunctor() // << first calls the original, then execute();
// To simply wrap a previous function, don't define execute() in the prototype.

牛が帰ってくるまで、無数の他のオブジェクト/機能などをチェーンバインドすることもできます。プロキシ呼び出しを少しリファクタリングするだけです。

お役に立てば幸いです。もちろん、ファクトリーフローを変更して、newオペレーターなしで呼び出されたコンストラクターが新しいオブジェクトをインスタンス化してファンクターオブジェクトを返すようにすることもできます。しかし、あなたは好む(あなたは確かに他の方法でもそれをすることができる)。

最後に、関数をもう少しエレガントな方法でファンクターの実行演算子にするには、プロキシ関数をのメソッドにFunction.prototypeして、そのようなものを実行したい場合はラップするオブジェクトを渡します(スワップする必要があります)templateFunctionthisthis)のコースを引数としました...

var functor = (function() { /* something */ }).asFunctor(aobj);

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

別の関数のプロパティとメソッドを継承する関数をJavascriptで作成するにはどうすればよいですか?

分類Dev

C ++でメンバー関数のみを継承するにはどうすればよいですか?

分類Dev

Kotlin:「静的な」継承可能な関数を作成するにはどうすればよいですか?

分類Dev

reactjs関数オブジェクトで継承を行うにはどうすればよいですか?

分類Dev

DataGridColumnsを継承するにはどうすればよいですか

分類Dev

Visioで多重継承矢印の関係を作成するにはどうすればよいですか?

分類Dev

関数を継続させるにはどうすればよいですか?

分類Dev

すべての変数を親クラスからinit関数を持つ基本クラスに継承するにはどうすればよいですか?

分類Dev

複数のinit継承を使用してsuper()を実装するにはどうすればよいですか?

分類Dev

関数に返された関数の戻り値の型を継承させるにはどうすればよいですか?

分類Dev

継承可能なクラス変数を作成するにはどうすればよいですか?

分類Dev

さまざまな継承された引数で関数をオーバーライドするにはどうすればよいですか(Swift)

分類Dev

Awake()、Start()、UpdateおよびFixedUpdate()などのUnityのコールバック関数を正しく継承するにはどうすればよいですか?

分類Dev

親クラス関数で継承されたオブジェクトを使用するにはどうすればよいですか?

分類Dev

関数を別のクラスからkotlinのアクティビティに継承するにはどうすればよいですか?

分類Dev

Observable <T>から継承するにはどうすればよいですか?

分類Dev

instanceof関数を使用して継承で特定のカテゴリを出力するにはどうすればよいですか?

分類Dev

継承されたクラスの拡張機能の関数をオーバーライドするにはどうすればよいですか?

分類Dev

継承されたクラス関数をスレッドに与えるにはどうすればよいですか?

分類Dev

Python:他のABCから継承するABCを作成するにはどうすればよいですか?

分類Dev

SQLAlchemyで継承された列に制約を定義するにはどうすればよいですか?

分類Dev

クラス継承を使用して引数を渡すにはどうすればよいですか?

分類Dev

継承されたクラスで親クラス変数の値を設定し、それを継承された関数で使用するにはどうすればよいですか?

分類Dev

javascriptで関係を継続的に更新するにはどうすればよいですか?

分類Dev

Hibernate JPA @NamedEntityGraphで継承された属性を参照するにはどうすればよいですか?

分類Dev

JavaScript関数を終了するにはどうすればよいですか?

分類Dev

JavaScript関数を停止するにはどうすればよいですか?

分類Dev

さまざまに継承されたすべてのクラスの関数を呼び出すにはどうすればよいですか?

分類Dev

CSSで継承を無効にするにはどうすればよいですか?

Related 関連記事

  1. 1

    別の関数のプロパティとメソッドを継承する関数をJavascriptで作成するにはどうすればよいですか?

  2. 2

    C ++でメンバー関数のみを継承するにはどうすればよいですか?

  3. 3

    Kotlin:「静的な」継承可能な関数を作成するにはどうすればよいですか?

  4. 4

    reactjs関数オブジェクトで継承を行うにはどうすればよいですか?

  5. 5

    DataGridColumnsを継承するにはどうすればよいですか

  6. 6

    Visioで多重継承矢印の関係を作成するにはどうすればよいですか?

  7. 7

    関数を継続させるにはどうすればよいですか?

  8. 8

    すべての変数を親クラスからinit関数を持つ基本クラスに継承するにはどうすればよいですか?

  9. 9

    複数のinit継承を使用してsuper()を実装するにはどうすればよいですか?

  10. 10

    関数に返された関数の戻り値の型を継承させるにはどうすればよいですか?

  11. 11

    継承可能なクラス変数を作成するにはどうすればよいですか?

  12. 12

    さまざまな継承された引数で関数をオーバーライドするにはどうすればよいですか(Swift)

  13. 13

    Awake()、Start()、UpdateおよびFixedUpdate()などのUnityのコールバック関数を正しく継承するにはどうすればよいですか?

  14. 14

    親クラス関数で継承されたオブジェクトを使用するにはどうすればよいですか?

  15. 15

    関数を別のクラスからkotlinのアクティビティに継承するにはどうすればよいですか?

  16. 16

    Observable <T>から継承するにはどうすればよいですか?

  17. 17

    instanceof関数を使用して継承で特定のカテゴリを出力するにはどうすればよいですか?

  18. 18

    継承されたクラスの拡張機能の関数をオーバーライドするにはどうすればよいですか?

  19. 19

    継承されたクラス関数をスレッドに与えるにはどうすればよいですか?

  20. 20

    Python:他のABCから継承するABCを作成するにはどうすればよいですか?

  21. 21

    SQLAlchemyで継承された列に制約を定義するにはどうすればよいですか?

  22. 22

    クラス継承を使用して引数を渡すにはどうすればよいですか?

  23. 23

    継承されたクラスで親クラス変数の値を設定し、それを継承された関数で使用するにはどうすればよいですか?

  24. 24

    javascriptで関係を継続的に更新するにはどうすればよいですか?

  25. 25

    Hibernate JPA @NamedEntityGraphで継承された属性を参照するにはどうすればよいですか?

  26. 26

    JavaScript関数を終了するにはどうすればよいですか?

  27. 27

    JavaScript関数を停止するにはどうすればよいですか?

  28. 28

    さまざまに継承されたすべてのクラスの関数を呼び出すにはどうすればよいですか?

  29. 29

    CSSで継承を無効にするにはどうすればよいですか?

ホットタグ

アーカイブ