ES6クラスで関数を拡張する方法は?


105

ES6では、特別なオブジェクトを拡張できます。そのため、関数から継承することが可能です。そのようなオブジェクトは関数として呼び出すことができますが、そのような呼び出しのロジックをどのように実装できますか?

class Smth extends Function {
  constructor (x) {
    // What should be done here
    super();
  }
}

(new Smth(256))() // to get 256 at this call?

クラスのどのメソッドも、を介してクラスインスタンスへの参照を取得しますthis。ただし、関数として呼び出される場合は、をthis参照してくださいwindow。関数として呼び出されたときに、クラスインスタンスへの参照を取得するにはどうすればよいですか?

PS:ロシア語でも同じ質問です。


17
ああ、ついに誰かがこのquestonを尋ねた:-)
Bergi

1
ただ行うsuper(x)(つまり、それをに渡すFunction)?Function実際に拡張できるかどうかはわかりません。
Felix Kling

組み込みクラスの拡張にはまだ問題があることに注意してください。仕様はそれが可能であるべきだと示唆していますが、私はErrorとりわけ拡張の問題に遭遇しました。
ssube

1
これFunctionは単なる関数コンストラクターであることに注意してください。関数の実装をコンストラクタに渡す必要があります。Smth実装を受け入れたくない場合は、コンストラクターで実装する必要がありますsuper('function implementation here')
Felix Kling

1
@Qwertiy:これは例外であり、一般的なケースではないと主張します。これも関数式に非常に固有ですがFunction、関数式(構文)とは非常に異なるコンストラクター(ランタイム)を使用しています。
Felix Kling

回答:


49

super呼び出しが起動しますFunctionコード文字列を期待コンストラクタを、。インスタンスデータにアクセスする場合は、ハードコードするだけです。

class Smth extends Function {
  constructor(x) {
    super("return "+JSON.stringify(x)+";");
  }
}

しかし、それは本当に満足できるものではありません。クロージャーを使用したい。

返された関数をインスタンス変数にアクセスできるクロージャーにすることは可能ですが、簡単ではありません。良いことは、呼び出しsuperたくない場合に呼び出す必要がないことです。それでもreturn、ES6クラスコンストラクタから任意のオブジェクトを呼び出すことができます。この場合は、

class Smth extends Function {
  constructor(x) {
    // refer to `smth` instead of `this`
    function smth() { return x; };
    Object.setPrototypeOf(smth, Smth.prototype);
    return smth;
  }
}

しかし、私たちはもっとうまくやることができ、このことを抽象化しますSmth

class ExtensibleFunction extends Function {
  constructor(f) {
    return Object.setPrototypeOf(f, new.target.prototype);
  }
}

class Smth extends ExtensibleFunction {
  constructor(x) {
    super(function() { return x; }); // closure
    // console.log(this); // function() { return x; }
    // console.log(this.prototype); // {constructor: …}
  }
}
class Anth extends ExtensibleFunction {
  constructor(x) {
    super(() => { return this.x; }); // arrow function, no prototype object created
    this.x = x;
  }
}
class Evth extends ExtensibleFunction {
  constructor(x) {
    super(function f() { return f.x; }); // named function
    this.x = x;
  }
}

確かに、これは継承チェーンに間接的なレベルを追加しますが、それは必ずしも悪いことではありません(ネイティブの代わりに拡張できますFunction)。それを避けたい場合は、

function ExtensibleFunction(f) {
  return Object.setPrototypeOf(f, new.target.prototype);
}
ExtensibleFunction.prototype = Function.prototype;

ただし、Smth静的Functionプロパティを動的に継承しないことに注意してください。


関数からクラスの状態にアクセスしたい。
Qwertiy

2
@Qwertiy:次に、ベルギの2番目の提案を使用します。
Felix Kling

@ AlexanderO'Mara:(誰もが期待するように)Smthインスタンスにしたい場合は、関数のプロトタイプを変更する必要はありませんinstanceof SmthObject.setPrototypeOfこれまたはクラスで宣言されているプロトタイプメソッドが必要ない場合は、呼び出しを省略できます。
Bergi

@ AlexanderO'Mara:Object.setPrototypeOfオブジェクトの作成直後に行われる限り、最適化の問題はそれほどありません。オブジェクトの[[プロトタイプ]]をその有効期間中に前後に変異させた場合、それは悪いことです。
Bergi

1
ノー@amn、あなたは、あなたが使用していないとき、ないthisreturnオブジェクト。
ベルギ

32

これは、プロトタイプをいじることなく、オブジェクトメンバーを正しく参照し、正しい継承を維持する呼び出し可能なオブジェクトを作成する方法です。

単に:

class ExFunc extends Function {
  constructor() {
    super('...args', 'return this.__self__.__call__(...args)')
    var self = this.bind(this)
    this.__self__ = self
    return self
  }

  // Example `__call__` method.
  __call__(a, b, c) {
    return [a, b, c];
  }
}

このクラスを拡張し、__call__メソッドを追加します。

コードとコメントの説明:

// This is an approach to creating callable objects
// that correctly reference their own object and object members,
// without messing with prototypes.

// A Class that extends Function so we can create
// objects that also behave like functions, i.e. callable objects.
class ExFunc extends Function {
  constructor() {
    super('...args', 'return this.__self__.__call__(...args)');
    // Here we create a function dynamically using `super`, which calls
    // the `Function` constructor which we are inheriting from. Our aim is to create
    // a `Function` object that, when called, will pass the call along to an internal
    // method `__call__`, to appear as though the object is callable. Our problem is
    // that the code inside our function can't find the `__call__` method, because it
    // has no reference to itself, the `this` object we just created.
    // The `this` reference inside a function is called its context. We need to give
    // our new `Function` object a `this` context of itself, so that it can access
    // the `__call__` method and any other properties/methods attached to it.
    // We can do this with `bind`:
    var self = this.bind(this);
    // We've wrapped our function object `this` in a bound function object, that
    // provides a fixed context to the function, in this case itself.
    this.__self__ = self;
    // Now we have a new wrinkle, our function has a context of our `this` object but
    // we are going to return the bound function from our constructor instead of the
    // original `this`, so that it is callable. But the bound function is a wrapper
    // around our original `this`, so anything we add to it won't be seen by the
    // code running inside our function. An easy fix is to add a reference to the
    // new `this` stored in `self` to the old `this` as `__self__`. Now our functions
    // context can find the bound version of itself by following `this.__self__`.
    self.person = 'Hank'
    return self;
  }
  
  // An example property to demonstrate member access.
  get venture() {
    return this.person;
  }
  
  // Override this method in subclasses of ExFunc to take whatever arguments
  // you want and perform whatever logic you like. It will be called whenever
  // you use the obj as a function.
  __call__(a, b, c) {
    return [this.venture, a, b, c];
  }
}

// A subclass of ExFunc with an overridden __call__ method.
class DaFunc extends ExFunc {
  constructor() {
    super()
    this.a = 'a1'
    this.b = 'b2'
    this.person = 'Dean'
  }

  ab() {
    return this.a + this.b
  }
  
  __call__(ans) {
    return [this.ab(), this.venture, ans];
  }
}

// Create objects from ExFunc and its subclass.
var callable1 = new ExFunc();
var callable2 = new DaFunc();

// Inheritance is correctly maintained.
console.log('\nInheritance maintained:');
console.log(callable2 instanceof Function);  // true
console.log(callable2 instanceof ExFunc);  // true
console.log(callable2 instanceof DaFunc);  // true

// Test ExFunc and its subclass objects by calling them like functions.
console.log('\nCallable objects:');
console.log( callable1(1, 2, 3) );  // [ 'Hank', 1, 2, 3 ]
console.log( callable2(42) );  // [ 'a1b2', Dean', 42 ]

// Test property and method access
console.log(callable2.a, callable2.b, callable2.ab())

repl.itで表示

のさらなる説明bind

function.bind()はとほぼ同じようfunction.call()に機能し、同様のメソッドシグネチャを共有します。

fn.call(this, arg1, arg2, arg3, ...);もっと上のMDN

fn.bind(this, arg1, arg2, arg3, ...);もっと上のMDN

どちらの場合も、最初の引数thisは関数内のコンテキストを再定義します。追加の引数も値にバインドできます。しかしcall、バインドされた値で関数をすぐに呼び出す場合、bindthisと、引数が事前設定されており、元のオブジェクトを透過的にラップする「エキゾチックな」関数オブジェクトが返されます。

したがって、関数を定義すると、bindその引数の一部が次のようになります。

var foo = function(a, b) {
  console.log(this);
  return a * b;
}

foo = foo.bind(['hello'], 2);

残りの引数のみを使用してバインドされた関数を呼び出します。そのコンテキストは事前設定されており、この場合は['hello']です。

// We pass in arg `b` only because arg `a` is already set.
foo(2);  // returns 4, logs `['hello']`

なぜbind機能するのか(つまり、のインスタンスが返される理由)の説明を追加していただけますExFuncか?
Bergi

@Bergi bindは、呼び出された関数オブジェクト(呼び出し可能なオブジェクト)をラップする透過的な関数オブジェクトを、thisコンテキストがリバウンドされた状態で返します。したがって、それは透過的にラップされたのインスタンスを本当に返しますExFunc。に関する詳細情報で更新された投稿bind
Adrien 2016年

1
@Bergiすべてのゲッター/セッターとメソッドにアクセスでき、プロパティ/属性はconstructor後から割り当てる必要がありますbindExFunc。ExFuncのサブクラスでは、すべてのメンバーがアクセス可能です。instanceof、es6では、バインドされた関数はエキゾチックと呼ばれるため、内部の動作は明らかではありませんが、ラップされたターゲットにを介して呼び出しを渡していると思いSymbol.hasInstanceます。プロキシによく似ていますが、目的の効果を実現するための簡単な方法です。彼らの署名は同じではなく似ています。
Adrien 2016年

1
@Adrienが、内側から__call__、私はアクセスすることはできませんthis.athis.ab()。例:repl.it/repls/FelineFinishedDesktopenvironment
rob

1
@robはよく見つかりました。参照エラーがあり、回答とコードを修正して新しい説明で更新しました。
エイドリアン

20

Smthインスタンスを 、プロキシapply(そしておそらくconstruct)トラップ:

class Smth extends Function {
  constructor (x) {
    super();
    return new Proxy(this, {
      apply: function(target, thisArg, argumentsList) {
        return x;
      }
    });
  }
}
new Smth(256)(); // 256

クールなアイデア。このような。applyの内部に配置する代わりに、もう少しロジックを実装する必要がありますか?
Qwertiy

4
プロキシはかなりのオーバーヘッドを招くでしょうね。また、this空の関数です(チェックnew Smth().toString())。
Bergi

2
@Bergiパフォーマンスについてはわかりません。MDNには大きな赤い太字の警告がsetPrototypeOfあり、プロキシについては何も言われません。しかし、プロキシはと同じくらい問題が多いと思いますsetPrototypeOf。またtoString、のカスタムメソッドを使用してシャドウすることができますSmth.prototype。とにかく、ネイティブのものは実装依存です。
Oriol

@Qwertiy constructトラップを追加して、の動作を指定できますnew new Smth(256)()。そしてtoString、Bergiが指摘したように、関数のコードにアクセスするネイティブメソッドをシャドウするカスタムメソッドを追加します。
Oriol

私はMENTあなたれるapply方法は、使用されることを想定しているように実装、またはそれだけでデモであると私は詳細な情報に目を通す必要があるProxyReflect適切な方法でそれを使用しますか?
Qwertiy

3

Bergiの回答からアドバイスを受け取り、それをNPMモジュールにラップしました。

var CallableInstance = require('callable-instance');

class ExampleClass extends CallableInstance {
  constructor() {
    // CallableInstance accepts the name of the property to use as the callable
    // method.
    super('instanceMethod');
  }

  instanceMethod() {
    console.log("instanceMethod called!");
  }
}

var test = new ExampleClass();
// Invoke the method normally
test.instanceMethod();
// Call the instance itself, redirects to instanceMethod
test();
// The instance is actually a closure bound to itself and can be used like a
// normal function.
test.apply(null, [ 1, 2, 3 ]);

3

更新:

残念ながら、クラスの代わりに関数オブジェクトを返すようになっているため、これはうまく機能しません。したがって、プロトタイプを変更せずにこれを実際に行うことはできないようです。ラメ。


基本的に問題はthisFunctionコンストラクタの値を設定する方法がないことです。これを実際に行う唯一の方法は、.bind後でメソッドを使用することですが、これはクラスフレンドリーではありません。

ヘルパー基本クラスでこれを行うことができますがthis、最初のsuper呼び出しの後まで利用可能にならないため、少し注意が必要です。

実例:

'use strict';

class ClassFunction extends function() {
    const func = Function.apply(null, arguments);
    let bound;
    return function() {
        if (!bound) {
            bound = arguments[0];
            return;
        }
        return func.apply(bound, arguments);
    }
} {
    constructor(...args) {
        (super(...args))(this);
    }
}

class Smth extends ClassFunction {
    constructor(x) {
        super('return this.x');
        this.x = x;
    }
}

console.log((new Smth(90))());

(例には、最新のブラウザまたはが必要ですnode --harmony。)

基本的に、基本関数ClassFunctionextendsは、Functionコンストラクター呼び出しをと同様のカスタム関数でラップし.bindますが、最初の呼び出しで後でバインドできます。次に、ClassFunctionコンストラクター自体でsuper、バインドされた関数である返された関数を呼び出しthis、カスタムバインド関数の設定を完了するために渡します。

(super(...))(this);

これはすべてかなり複雑ですが、プロトタイプの変更を回避します。プロトタイプは、最適化の理由から不正な形式と見なされ、ブラウザコンソールで警告を生成する可能性があります。


1
あなたは物事を複雑にしています。その匿名クラスからboundの関数を参照しますreturn。名前を付けて、直接参照してください。また、コード文字列を渡さないようにすることをお勧めします。これらは、(開発プロセスのすべてのステップで)作業するための混乱にすぎません。
Bergi

それはextends予想通り、本当にとして、動作するようには思えないFunction.isPrototypeOf(Smth)ともnew Smth instanceof Functionfalseです。
Bergi

@BergiどのJSエンジンを使用していますか?console.log((new Smth) instanceof Function);あるtrueノードv5.11.0と最新のFirefoxで私のために。
Alexander O'Mara

おっと、間違った例。それnew Smth instanceof Smthはあなたのソリューションではうまくいかないということです。またSmth、インスタンスではのメソッドを使用できません。- Functionではなく標準を返すだけSmthです。
Bergi

1
@Bergiくそー、それはあなたが正しいようです。ただし、ネイティブタイプを拡張しても同じ問題があるようです。extend Functionまた、new Smth instanceof Smth偽になります。
Alexander O'Mara

1

最初に私はで解決策をarguments.callee見つけましたが、それはひどいものでした。
私はそれがグローバルな厳格なモードで壊れると期待していましたが、それはそこでさえ機能するようです。

class Smth extends Function {
  constructor (x) {
    super('return arguments.callee.x');
    this.x = x;
  }
}

(new Smth(90))()

を使用しarguments.callee、コードを文字列として渡し、非厳密モードでの実行を強制するため、これは悪い方法でした。しかし、オーバーライドするという考えがapply現れました。

var global = (1,eval)("this");

class Smth extends Function {
  constructor(x) {
    super('return arguments.callee.apply(this, arguments)');
    this.x = x;
  }
  apply(me, [y]) {
    me = me !== global && me || this;
    return me.x + y;
  }
}

そしてテストは、これをさまざまな方法で関数として実行できることを示しています:

var f = new Smth(100);

[
f instanceof Smth,
f(1),
f.call(f, 2),
f.apply(f, [3]),
f.call(null, 4),
f.apply(null, [5]),
Function.prototype.apply.call(f, f, [6]),
Function.prototype.apply.call(f, null, [7]),
f.bind(f)(8),
f.bind(null)(9),
(new Smth(200)).call(new Smth(300), 1),
(new Smth(200)).apply(new Smth(300), [2]),
isNaN(f.apply(window, [1])) === isNaN(f.call(window, 1)),
isNaN(f.apply(window, [1])) === isNaN(Function.prototype.apply.call(f, window, [1])),
] == "true,101,102,103,104,105,106,107,108,109,301,302,true,true"

バージョン

super('return arguments.callee.apply(arguments.callee, arguments)');

実際にはbind機能が含まれています:

(new Smth(200)).call(new Smth(300), 1) === 201

バージョン

super('return arguments.callee.apply(this===(1,eval)("this") ? null : this, arguments)');
...
me = me || this;

作るcallapplywindow矛盾:

isNaN(f.apply(window, [1])) === isNaN(f.call(window, 1)),
isNaN(f.apply(window, [1])) === isNaN(Function.prototype.apply.call(f, window, [1])),

したがって、チェックは次の場所に移動する必要がありますapply

super('return arguments.callee.apply(this, arguments)');
...
me = me !== global && me || this;

1
実際に何をしようとしていますか?
ありがとう

2
私はクラスがstrictモードでは常にあると思います:stackoverflow.com/questions/29283935/...
アレクサンダーO'Mara

ちなみに、@ AlexanderO'Mara thisはウィンドウであり、未定義ではないため、作成された関数は(少なくともchromeでは)strictモードではありません。
Qwertiy 2016

この回答の取り下げはやめてください。私はそれが悪い方法だとすでに書いています。しかし、それは本当に答えです-FFとChromeの両方で機能します(確認するEdgeがありません)。
Qwertiy

Functionは厳密モードではないので、これはうまくいくと思います。ひどいですが、面白い+1です。あなたはおそらくそれ以上チェーンを歩くことができないでしょう。
Alexander O'Mara

1

これは、関数を拡張するという私のすべてのニーズに対応し、非常にうまく機能してきた私が解決したソリューションです。この手法の利点は次のとおりです。

  • 拡張ExtensibleFunction時のコードは、ES6クラスを拡張する慣用的なものです(いいえ、偽のコンストラクターまたはプロキシをいじくりまわしています)。
  • プロトタイプチェーンは、すべてのサブクラスによって保持され、instanceof/ .constructor期待値を返します。
  • .bind() .apply()そして.call()予想通り、すべての機能。これは、これらのメソッドをオーバーライドして、ExtensibleFunction(またはそのサブクラスの)インスタンスではなく「内部」関数のコンテキストを変更することによって行われます。
  • .bind()関数コンストラクタの新しいインスタンス(それExtensibleFunctionまたはサブクラス)を返します。Object.assign()バインドされた関数に格納されたプロパティが元の関数のプロパティと一致することを保証するために使用します。
  • クロージャーは尊重され、矢印関数は適切なコンテキストを維持し続けます。
  • 「内部」関数はSymbol、モジュールまたはIIFE(または参照をプライベート化する他の一般的な手法)によって難読化できるを介して保存されます。

そしてさらに苦労せずに、コード:

// The Symbol that becomes the key to the "inner" function 
const EFN_KEY = Symbol('ExtensibleFunctionKey');

// Here it is, the `ExtensibleFunction`!!!
class ExtensibleFunction extends Function {
  // Just pass in your function. 
  constructor (fn) {
    // This essentially calls Function() making this function look like:
    // `function (EFN_KEY, ...args) { return this[EFN_KEY](...args); }`
    // `EFN_KEY` is passed in because this function will escape the closure
    super('EFN_KEY, ...args','return this[EFN_KEY](...args)');
    // Create a new function from `this` that binds to `this` as the context
    // and `EFN_KEY` as the first argument.
    let ret = Function.prototype.bind.apply(this, [this, EFN_KEY]);
    // For both the original and bound funcitons, we need to set the `[EFN_KEY]`
    // property to the "inner" function. This is done with a getter to avoid
    // potential overwrites/enumeration
    Object.defineProperty(this, EFN_KEY, {get: ()=>fn});
    Object.defineProperty(ret, EFN_KEY, {get: ()=>fn});
    // Return the bound function
    return ret;
  }

  // We'll make `bind()` work just like it does normally
  bind (...args) {
    // We don't want to bind `this` because `this` doesn't have the execution context
    // It's the "inner" function that has the execution context.
    let fn = this[EFN_KEY].bind(...args);
    // Now we want to return a new instance of `this.constructor` with the newly bound
    // "inner" function. We also use `Object.assign` so the instance properties of `this`
    // are copied to the bound function.
    return Object.assign(new this.constructor(fn), this);
  }

  // Pretty much the same as `bind()`
  apply (...args) {
    // Self explanatory
    return this[EFN_KEY].apply(...args);
  }

  // Definitely the same as `apply()`
  call (...args) {
    return this[EFN_KEY].call(...args);
  }
}

/**
 * Below is just a bunch of code that tests many scenarios.
 * If you run this snippet and check your console (provided all ES6 features
 * and console.table are available in your browser [Chrome, Firefox?, Edge?])
 * you should get a fancy printout of the test results.
 */

// Just a couple constants so I don't have to type my strings out twice (or thrice).
const CONSTRUCTED_PROPERTY_VALUE = `Hi, I'm a property set during construction`;
const ADDITIONAL_PROPERTY_VALUE = `Hi, I'm a property added after construction`;

// Lets extend our `ExtensibleFunction` into an `ExtendedFunction`
class ExtendedFunction extends ExtensibleFunction {
  constructor (fn, ...args) {
    // Just use `super()` like any other class
    // You don't need to pass ...args here, but if you used them
    // in the super class, you might want to.
    super(fn, ...args);
    // Just use `this` like any other class. No more messing with fake return values!
    let [constructedPropertyValue, ...rest] = args;
    this.constructedProperty = constructedPropertyValue;
  }
}

// An instance of the extended function that can test both context and arguments
// It would work with arrow functions as well, but that would make testing `this` impossible.
// We pass in CONSTRUCTED_PROPERTY_VALUE just to prove that arguments can be passed
// into the constructor and used as normal
let fn = new ExtendedFunction(function (x) {
  // Add `this.y` to `x`
  // If either value isn't a number, coax it to one, else it's `0`
  return (this.y>>0) + (x>>0)
}, CONSTRUCTED_PROPERTY_VALUE);

// Add an additional property outside of the constructor
// to see if it works as expected
fn.additionalProperty = ADDITIONAL_PROPERTY_VALUE;

// Queue up my tests in a handy array of functions
// All of these should return true if it works
let tests = [
  ()=> fn instanceof Function, // true
  ()=> fn instanceof ExtensibleFunction, // true
  ()=> fn instanceof ExtendedFunction, // true
  ()=> fn.bind() instanceof Function, // true
  ()=> fn.bind() instanceof ExtensibleFunction, // true
  ()=> fn.bind() instanceof ExtendedFunction, // true
  ()=> fn.constructedProperty == CONSTRUCTED_PROPERTY_VALUE, // true
  ()=> fn.additionalProperty == ADDITIONAL_PROPERTY_VALUE, // true
  ()=> fn.constructor == ExtendedFunction, // true
  ()=> fn.constructedProperty == fn.bind().constructedProperty, // true
  ()=> fn.additionalProperty == fn.bind().additionalProperty, // true
  ()=> fn() == 0, // true
  ()=> fn(10) == 10, // true
  ()=> fn.apply({y:10}, [10]) == 20, // true
  ()=> fn.call({y:10}, 20) == 30, // true
  ()=> fn.bind({y:30})(10) == 40, // true
];

// Turn the tests / results into a printable object
let table = tests.map((test)=>(
  {test: test+'', result: test()}
));

// Print the test and result in a fancy table in the console.
// F12 much?
console.table(table);

編集する

気分が良かったので、このためのパッケージをnpmに公開すると思いました。


1

JavaScriptの機能を利用する簡単な解決策があります。「ロジック」を関数の引数としてクラスのコンストラクターに渡し、そのクラスのメソッドをその関数に割り当て、その関数をコンストラクターから結果として返します。

class Funk
{
    constructor (f)
    { let proto       = Funk.prototype;
      let methodNames = Object.getOwnPropertyNames (proto);
      methodNames.map (k => f[k] = this[k]);
      return f;
    }

    methodX () {return 3}
}

let myFunk  = new Funk (x => x + 1);
let two     = myFunk(1);         // == 2
let three   = myFunk.methodX();  // == 3

上記はNode.js 8でテストされました。

上記の例の欠点は、スーパークラスチェーンから継承されたメソッドをサポートしないことです。これをサポートするには、単に "Object。getOwnPropertyNames(...)"を、継承されたメソッドの名前も返すものに置き換えます。その方法は、スタックオーバーフローに関する他の質問と回答で説明されていると思います:-)。ところで。ES7が継承されたメソッドの名前も生成するメソッドを追加したとしたら、すばらしいでしょう;-)。

継承されたメソッドをサポートする必要がある場合、1つの可能性は、継承されたすべてのローカルメソッド名を返す静的メソッドを上記のクラスに追加することです。次に、コンストラクターから呼び出します。次に、そのクラスFunkを拡張すると、その静的メソッドも継承されます。


この例は、元の質問「このような呼び出しのロジックをどのように実装できるか」に対する簡単な答えを与えると思います。これを関数値引数としてコンストラクターに渡すだけです。上記のコードでは、クラスFunkはFunctionを明示的に拡張していませんが、実際には拡張する必要はありません。ご覧のように、通常の関数を呼び出すように、その「インスタンス」を呼び出すことができます。
Panu Logic 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.