0

これは、ハウツーの質問というよりも理論的な質問です。私は、オブジェクトをいくつかの異なる型に「区別」できるプロジェクトに取り組んでいたので、Javascript の動的機能のいくつかを調べることにしましたが、本当に混乱したことが 1 つあります。

OriginalConstructor = function() {this.value = 42;}
originalInstance = new OriginalConstructor();
ModifiedConstructor = eval(originalInstance.constructor);
ModifiedConstructor.prototype.addedFunction = function(x) {return this.value + x;}
modifiedInstance = new ModifiedConstructor();
document.write("modified: " + modifiedInstance.addedFunction(10));
document.write("<br>original: " + originalInstance.addedFunction(20));

を介してコピーされたにもかかわらず、がaddedFunctionにバインドされるのはなぜですか? 確かに、これら 2 つのコンストラクターが同じ参照を持つことはできませんね。originalInstanceModifiedConstructoreval()

同じコンストラクターから既にインスタンス化されている他のオブジェクトに影響を与えることなく、オブジェクト (または将来のインスタンス) を変更する方法はありますか? これにアプローチする他の方法があることは知っていますが、Javascript をより深いレベルで理解したいと考えています。あなたが提供できる洞察に感謝します。

@Felix Kling: 迅速で明確で完全な回答をありがとう。どういうわけか、コンストラクターのプロパティは eval() で解析できる文字列だと思っていたので、これが機能しなかった理由がわかりました。プロトタイプの継承についてはまだ完全には理解できていませんが、少なくとも何を研究する必要があるかはわかりました。ありがとうございました!

編集:私は今それを取得します。古典的な OOP のバックグラウンドを持っている場合、プロトタイプの継承はかなり奇妙に思えますが、概念的には単純で理解しやすく、実際にはいくつかの点でより強力です。Javascript のプロトタイプの継承について詳しく知りたい場合は、次の記事を強くお勧めします。

http://javascript.crockford.com/prototypal.html

http://www.laktek.com/2011/02/02/understanding-prototyping-inheritance-in-javascript/

http://blog.vjeux.com/2011/javascript/how-prototypal-inheritance-really-works.html

http://howtonode.org/prototyping-inheritance

また、この種の柔軟性が必要な場合は、「エンティティ システム」の使用を検討することをお勧めします。これは、複雑な継承階層に代わるものとしていくつかの利点を提供します。エンティティ システムに関するほとんどの記事はゲーム開発に焦点を当てていますが、このアーキテクチャは他のアプリケーションにも役立つと思います。これは OOP プログラマーにとって非常になじみのない概念なので、OOP について知っていることはすべて脇に置いて、リレーショナル データベース設計の観点から考えてください。見てみな:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

4

1 に答える 1

4

ModifiedConstructor はのコピーではなくOriginalConstructor、まったく同じ機能です。

evalのアルゴリズムの最初の命令は次のとおりです。

Type( x ) が String でない場合、 xを返します。

つまり、単純に渡したものを返しOriginalConstructor === ModifiedConstructorますtrue

同じコンストラクターから既にインスタンス化されている他のオブジェクトに影響を与えることなく、オブジェクト (または将来のインスタンス) を変更する方法はありますか?

プロトタイプの継承により、次のことができます。

ModifiedConstructor = function() {
    OriginalConstructor.apply(this, arguments);
};

ModifiedConstructor.prototype = Object.create(OriginalConstructor.prototype);
ModifiedConstructor.prototype.constructor = ModifiedConstructor;

ModifiedConstructor.prototypeによって作成されたインスタンスに影響を与えることなく、 に関数を追加できるようになりましたOriginalConstructor

すでに作成されたインスタンスが拡張されるのを防ぎたいだけの場合は、上書きするだけで済みますがOriginalConstructor.prototype、これはクリーンなソリューションではなくinstanceOf、既存のインスタンスでも機能しなくなります。

于 2012-10-26T03:03:17.967 に答える