[解決済み] すでにインスタンス化されているJavaScriptオブジェクトのプロトタイプを設定するには?
質問
例えば、以下のようなオブジェクトがあるとします。
foo
をJavaScriptのコードに書いたとします。
foo
は複雑なオブジェクトで、どこか他の場所で生成されています。 のプロトタイプを変更するにはどうしたらよいでしょうか?
foo
オブジェクトのプロトタイプを変更するにはどうしたらよいでしょうか?
私の動機は、.NETからJavaScriptのリテラルにシリアル化されたオブジェクトに適切なプロトタイプを設定することです。
私がASP.NETページ内で次のJavaScriptコードを書いたとします。
var foo = <%=MyData %>;
仮に
MyData
は、.NET の
JavaScriptSerializer
の上で
Dictionary<string,string>
オブジェクトを作成します。
実行時には以下のようになる。
var foo = [{"A":"1","B":"2"},{"X":"7","Y":"8"}];
ご覧のように
foo
はオブジェクトの配列になります。を初期化できるようにしたい。
foo
を適切なプロトタイプで初期化できるようにしたい。私は
ではなく
を修正したいのです。
Object.prototype
も
Array.prototype
. どうすればいいのでしょうか?
どのように解決するのですか?
更新してください。 ES6で指定されるようになった Object.setPrototypeOf(オブジェクト, プロトタイプ).
2012年2月編集:以下の回答は、もはや正確ではありません。 プロト は ECMAScript 6 に "normative optional" として追加されました。これは、実装する必要はないが、実装する場合は与えられたルールのセットに従わなければならないことを意味します。これは現在未解決ですが、少なくとも公式に JavaScript の仕様の一部となる予定です。
この質問は表面的に見えるよりもずっと複雑で、Javascript の内部に関する知識に関して、ほとんどの人の給与水準を越えています。
その
prototype
プロパティは、そのオブジェクトの新しい子オブジェクトを作成するときに使用されます。これを変更してもオブジェクト自体には反映されず、むしろそのオブジェクトが他のオブジェクトのコンストラクタとして使用されるときに反映され、既存のオブジェクトのプロトタイプを変更することには使用されません。
function myFactory(){};
myFactory.prototype = someOtherObject;
var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true
オブジェクトは内部に[[prototype]]プロパティを持っており、これは現在のプロトタイプを指しています。オブジェクトのプロパティが呼び出されるたびに、オブジェクトから始まり、ルートオブジェクトのプロトタイプの後に一致するか失敗するまで [[prototype]] チェーンを上がっていく仕組みになっています。これは、Javascript がオブジェクトの実行時の構築と修正を可能にする方法です。
は
__proto__
プロパティはいくつかの実装に存在します(現在は多く存在します): すべての Mozilla の実装、私が知っているすべての webkit の実装、その他です。このプロパティは内部の [[prototype]] プロパティを指し、オブジェクトの作成後の変更を可能にします。すべてのプロパティと関数は、この連鎖したルックアップにより、プロトタイプに一致するように即座に切り替わります。
この機能は、現在標準化されているとはいえ、まだ JavaScript の必須部分ではありませんし、それをサポートする言語では、あなたのコードを "unoptimized" のカテゴリに叩き落とす可能性が高くなります。JSエンジンはコードの分類に最善を尽くさなければならず、特に頻繁にアクセスされる "hot" コードは、もしあなたが
__proto__
を修正するような派手なことをしている場合、あなたのコードをまったく最適化しません。
この投稿は
https://bugzilla.mozilla.org/show_bug.cgi?id=607863
の現在の実装を特に議論しています。
__proto__
の現在の実装と、それらの間の違いについて具体的に説明しています。なぜなら、これは難しく未解決の問題だからです。Javascriptでは、a.) 構文 b.) ホストオブジェクト (DOMは技術的にはJavascriptの外に存在します) と c.) を除いて、すべてが変更可能です。
__proto__
. 残りは完全にあなたや他のすべての開発者の手に委ねられているので、なぜ
__proto__
が突出している理由がわかると思います。
ひとつだけ
__proto__
それは、オブジェクトのプロトタイプをそのコンストラクタとは別に実行時に指定することです。これは重要なユースケースであり、また
__proto__
がまだ死んでいない主な理由の 1 つです。これは、Harmony、またはまもなく ECMAScript 6 として知られるようになるものの策定において、重大な論点となったほど重要なことなのです。オブジェクトの作成時にプロトタイプを指定する機能は、Javascript の次のバージョンの一部となり、これがベルを示すことになります。
__proto__
の日数が正式に決定されました。
短期的には
__proto__
をサポートしているブラウザをターゲットにしている場合は、それを使用できます (IE ではありませんし、今後もそうなることはないでしょう)。ES6 が完成するのは 2013 年なので、今後 10 年間は webkit と moz で動作する可能性があります。
Brendan Eich - re: ES5 の新しい Object メソッドのアプローチ :
<ブロッククオート
申し訳ありませんが、......設定可能な
__proto__
は、オブジェクトのイニシャライザーのユースケース(つまり、ES5 の Object.create に類似した、まだ到達していない新しいオブジェクト)を除けば、ひどいアイデアです。私はこれを、設定可能な
__proto__
を 12 年以上前に設計し、実装したことがあります。
... 階層化されていないことが問題(JSONデータでキーが
"__proto__"
). さらに悪いことに、ミュータビリティは、ilooping を避けるために、実装がプロトタイプの循環的な連鎖をチェックする必要があることを意味します。
[無限再帰のための一定のチェックが必要] です。
最後に、ミューティング
__proto__
を実行すると、新しいプロトタイプオブジェクトの非ジェネリックメソッドが壊れる可能性があり、そのメソッドは
__proto__
が設定されているレシーバ (直接の) オブジェクトでは動作しない可能性があります。これは単に悪い習慣であり、一般に意図的な型の混乱の一形態です。
関連
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] JavaScriptで現在の日付を取得するには?
-
[解決済み] JavaScript でオブジェクトが特定のプロパティを持つかどうかを確認するにはどうすればよいですか?
-
[解決済み] URL/アドレスバーからJavascriptの関数を呼び出す
-
[解決済み] bootstrap のポップオーバーがすべての要素の上に表示されない
-
[解決済み] Promise : then vs then + catch [重複].
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法
-
[解決済み] Fetch: ステータスがOKでない場合、プロミスを拒否し、エラーをキャッチするか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] javascriptで2つの数値を連結する方法は?
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] サブドメインにまたがってlocalStorageを使用する
-
[解決済み] moment.jsでミュータビリティを回避するには?
-
[解決済み] TypeScriptプロジェクトで既存のC#クラス定義を再利用する方法
-
[解決済み] イテレータでmap()を使用する
-
[解決済み] javascriptのキャンバスで画像をリサイズする (スムーズ)
-
[解決済み] JavaScriptデータフォーマット/プリティプリンタ