1. ホーム
  2. javascript

[解決済み] Object.create()とnew SomeFunction()の違いを理解する

2022-03-24 15:48:38

質問

最近、偶然に 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 ではありません。

このメソッドは、最新のブラウザでネイティブに実装され始めているので、以下をチェックしてみてください。 互換性テーブル .