2

私は es2016 の機能と少し混乱していますが、 と と比較してclass、クラスを作成するための単なる構文糖衣であると想定されていますが、場合によっては動作が異なります。特に、クラスを呼び出すことはできません関数と同じで、 と を使用せずに、関数がクラス コンストラクターであるか単純な関数であるかを調べる方法はないようです。functionprototypetoString/^class/ RegExp

次の例を想定します。

class Foo {
    constructor () {
        this.name = 'foo';
    }
}
function Bar () {
    this.name = 'bar';
}

function doSmth (anyArg) {
    if (typeof anyArg === 'function') {
        var obj = { someProp: 'qux' };
        anyArg.call(obj);
        return obj;
    }
    // ...
}


doSmth(Bar);
doSmth(Foo); // Class constructor Foo cannot be invoked without 'new'

ですtypeof 'function'が、関数として呼び出すことはできません! 良い。

そして、ここに私の2つの質問があります:

  1. オーバーライドされたコンテキストとFoo同じようにコンストラクター関数を呼び出す方法はありますか?Barthis
  2. anyArg関数で別の方法で処理できるように、クラスのコンストラクターであることを検出できる方法はありますかdoSmth。なし(この場合toStringパフォーマンスのペナルティが非常に大きくなるため)。次に、新しいインスタンスを初期化し、インスタンスからの値で変数を拡張するために使用できます。RegExpReflect.constructObject.assignobj

ありがとう、アレックス

4

3 に答える 3

0

最初の質問であなたが尋ねたことを行う方法がわかりません。

2 番目の質問では、実際に自分で違いを見分ける方法を特定しました。クラス コンストラクターとコンストラクターとして使用される関数の違いの 1 つは、前者はnewキーワードなしで使用するとエラーになり、後者はエラーにならないことです。

したがって、try/catch を使用すると、大まかにやりたいことを実行できます。

class Foo {
    constructor () {
        this.name = 'foo';
    }
}
function Bar () {
    this.name = 'bar';
}

function doSmth (anyArg) {
    if (typeof anyArg === 'function') {
        var obj = { someProp: 'qux' };
        try {
          anyArg.call(obj);
        } catch(e) {
          var x = Reflect.construct(anyArg, []);
          Object.assign(obj, x);
        }
        return obj;
    }
}


doSmth(Bar);
doSmth(Foo);

明確にするために、これが良いアイデア、良いコード、または探しているパフォーマンスを備えていることを示唆しているわけではありませんが、可能性が存在することを指摘したいと思いました。

于 2016-11-17T14:00:19.830 に答える
0

RegEx のパフォーマンスの低下が気になる場合は、 を使用してsubstring()ください。それでも文字列操作のパフォーマンスが気になる場合は、関数型を実際に区別する別の言語を検討してください。JavaScript では、それらはすべてfunction.

class Foo {
  constructor() {
    this.name = 'foo';
  }
}

function Bar() {
  this.name = 'bar';
}

function doSmth(anyArg) {
  if (typeof anyArg === 'function') {
    var obj = {
      someProp: 'qux'
    };
    if (anyArg.toString().substring(0, 5) === 'class') {
      Object.assign(obj, new anyArg());
    } else {
      anyArg.call(obj);
    }
    return obj;
  }
  // ...
}

var bar = doSmth(Bar);
var foo = doSmth(Foo);

console.log(bar);
console.log(foo);

于 2016-11-17T14:21:39.820 に答える