[解決済み] Object.create()とnew SomeFunction()の違いを理解する
質問
最近、偶然に
Object.create()
メソッドでオブジェクトの新しいインスタンスを作成するのとどのように違うのか推論しようとしています。
new SomeFunction()
また、どのような場合にどちらを使うべきでしょうか。
次のような例を考えてみましょう。
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
どちらのケースでも同じ動作が観察されることに注意してください。 この2つのシナリオの主な違いは、次のようなものだと思われます。
-
で使用されるオブジェクトは
Object.create()
は実際に新しいオブジェクトのプロトタイプを形成しています。new Function()
から、宣言されたプロパティ/関数はプロトタイプを形成しない。 -
でクロージャを作成することはできません。
Object.create()
の構文は、関数構文と同じように使用できます。 これは、JavaScript のレキシカル (対ブロック) 型のスコープを考えると、論理的なことです。
上記の記述は正しいですか?また、私は何かを見逃していませんか? どのような場合にどちらかを使うのでしょうか?
EDIT: 上記コードサンプルのjsfiddle版へのリンクです。 http://jsfiddle.net/rZfYL/
解決方法は?
<ブロッククオートObject.create で使用されるオブジェクトは、実際に新しいオブジェクトのプロトタイプを形成します。一方、new Function() のフォームでは、宣言されたプロパティ/関数がプロトタイプを形成しません。
そうですね。
Object.create
は、最初の引数として渡されたオブジェクトを直接継承したオブジェクトを構築します。
コンストラクタ関数の場合、新しく生成されたオブジェクトはコンストラクタのプロトタイプを継承する、といった具合です。
var o = new SomeConstructor();
上記の例では
o
を直接継承しています。
SomeConstructor.prototype
.
ここで違いがあるのは
Object.create
では、何も継承しないオブジェクトを作成することができます。
Object.create(null);
を設定した場合、一方では
SomeConstructor.prototype = null;
を継承し、新しく作成されたオブジェクトは
Object.prototype
.
Object.create 構文では、関数構文と同じようにクロージャを作成することはできません。これは、JavaScriptのレキシカル(対ブロック)な型スコープを考えると、論理的なことです。
ただし、プロパティディスクリプタの引数を使って、クロージャを作成することはできます。
var o = Object.create({inherited: 1}, {
foo: {
get: (function () { // a closure
var closured = 'foo';
return function () {
return closured+'bar';
};
})()
}
});
o.foo; // "foobar"
ECMAScript 第5版の話であることに注意してください。
Object.create
メソッドであり、Crockford's shim ではありません。
このメソッドは、最新のブラウザでネイティブに実装され始めているので、以下をチェックしてみてください。 互換性テーブル .
関連
-
fetch ネットワークリクエストラッパーの説明例
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
[解決済み】event.stopPropagationとevent.preventDefaultの違いは何ですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] JavaScriptの「new」キーワードとは何ですか?
-
[解決済み] Bowerとnpmの違いは何ですか?
-
[解決済み] JavaScriptのnullとundefinedの違いは何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Error : 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み] 配列の結合時に未定義のプロパティ 'push' を読み込むことができない
-
[解決済み】React Nativeアプリをターミナルから実行するとエラーが発生する(iOS)
-
[解決済み】TypeScript-のAngular Frameworkエラー - "exportAsがngFormに設定されたディレクティブはありません"
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
[解決済み】<select>で現在選択されている<option>をJavaScriptで取得するにはどうすればよいですか?
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
jq は html ページとデータを動的に分割する。