1

オブジェクト コンストラクターである childType プロパティを持つ JavaScript オブジェクトがあり、汎用の addChild メソッドを記述したいとします。this.childType のインスタンスを作成し、そのコンストラクターを呼び出して、渡された引数を addChild に渡す必要があります。

明確にするために、ポイントは、渡された子オブジェクトの型を検証するのではなく、継承された汎用 addChild メソッドとその既知の childType を使用して、各コレクションが子オブジェクト自体を作成することです。

これが難しいとは思っていませんでしたが、いろいろ試してみましたが、今のところ失敗しかありません。

アップデート:

これまでに知っている最善の解決策でデモ プランクを更新し、コードに問題に関するコメントをいくつか含めました。以下で説明する失敗した試行はなくなりました。このソリューションでは、可能性のあるすべての chhold オブジェクトに「新しい不可知論的コンストラクター」が必要になるため、まだ理想的ではありません。さらなる考えは大歓迎です。


次の 2 つの理由から、この行が間違っていることはわかっています。

var child = new this.childItemType.call(args);

まず、ある種の「this」を呼び出し関数に渡す必要があると思いますが、そこに何があるかわかりません。

2 番目はおそらく最初の結果であり、ブラウザで報告されたエラーです。

Uncaught TypeError: function call() { [native code] } is not a constructor

これは実行可能だと思いますが、 this.childType と渡された引数からその子オブジェクトを作成するための構文は、これまでのところ私を逃れています。誰かがここに欠けている脳細胞を指摘できますか?

4

5 に答える 5

2

おそらく最もクリーンなアプローチは、Dog を「new不可知論的」にすることです (有効な JavaScript 項目 33 を参照)。呼び出し方法に関係なく、Dogコンストラクターが new を返す方法に注意してください。Dog

var Dog = function (name)
{
  if(!(this instanceof Dog)){
    return new Dog(name);
  }

  this.name = name;
  return this;
};

そして、呼び出しの代わりに「適用」を使用しました。

var child = this.childItemType.apply(null,arguments);

これは、すべてのコンストラクターにとってちょっとした儀式のように見えますが、実際にはかなり良いアイデアです。私は自分のオブジェクトのほとんどをnew不可知論者にしていることに気づきました。

于 2013-03-18T13:24:51.300 に答える
1

そしてnewarguments不可知論的なワンライナーは次のようになります:)

var Dog = function( name ) {
    if ( !(this instanceof Dog) ) { return new (Dog.bind.apply( Dog, [null].concat( Array.prototype.slice.apply( arguments ) ) )); }

    this.name = name;

    return this;
}
于 2014-05-14T15:00:37.473 に答える
0

var child = 新しい this.childItemType.call(args);

いいえ、これは確かにFunction.prototype.callコンストラクターとして使用しようとします (例外メッセージが示すように)。ただし、使用する理由はまったくありませんcall

var child = new this.childItemType(arg, arg2, …);

まず、ある種の「this」を呼び出し関数に渡す必要があると思いますが、そこに何があるかわかりません。

はい、関数callの として何かが使用されることを期待してthisArgいます。それでも、argumens arrayapplyがあるので、必要なようです。 args

では、コンストラクターは何に適用されるのでしょうか? newこれは新しいインスタンスです -オペレーターが行うのと同じです。したがって、それを模倣するには、次を使用します

var child = Object.create(this.childItemType.prototype);
this.childItemType.apply(child, args);

Object.createコンストラクターなしで機能し、コンストラクターの戻り値の型をチェックするソリューションについては、「new」演算子での .apply() の使用を参照してください。これは可能ですか?.

于 2013-03-17T14:11:37.220 に答える
-1

正解は

var child = new this.childItemType(args);

JavaScriptでクラス/関数のオブジェクトを作成したい場合はnew ClassName(arguments)、直接行うことができます.callとapplyは通常、異なるスコープでクラス/関数のメソッドを呼び出すために使用されます

于 2013-03-15T19:14:04.533 に答える