回答:
それらは同等ではありません。{}.constructor.prototype == Object.prototype一方Object.create(null)、何も継承しないため、プロパティはまったくありません。
つまり、次のように、プロトタイプとしてnullを明示的に作成しない限り、JavaScriptオブジェクトはデフォルトでObjectを継承します。 Object.create(null)。
{}代わりにと同等になりObject.create(Object.prototype)ます。
Chrome Devtool Object.create(null)では、__proto__プロパティはあり{}ませんが、プロパティがあることがわかります。
それらは明らかに同等ではありません。私はこの答えを書いて、なぜそれが違いを生むのかをより完全に説明します。
var p = {};
からプロパティとメソッドを継承するオブジェクトを作成しますObject。
var p2 = Object.create(null);
何も継承しないオブジェクトを作成します。
オブジェクトをマップとして使用していて、上記の方法1を使用してオブジェクトを作成する場合、マップでルックアップを行うときは特に注意する必要があります。のプロパティとメソッドObjectが継承されるため、コードにマップ内に挿入したことのないキーがある場合があります。たとえば、でルックアップを行った場合toString、その値をそこに配置していなくても、関数が見つかります。あなたはこのようにそれを回避することができます:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
に何かを割り当てても問題ないことに注意してください。これはp.toString、継承されたtoString関数を単にオーバーライドするだけpです。
p.hasOwnProperty('toString')「hasOwnProperty」というキーをに挿入した可能性があるため、単に実行することはできませんp。したがって、Objectます。
一方、上記の方法2を使用する場合は、次のことについて心配する必要はありません。 Objectは、マップに表示さ。
次のifような単純な方法では、プロパティの存在を確認できません。
// Unreliable:
if (p[someKey]) {
// ...
}
値は空の文字列の場合もあればfalse、or null、or undefined、or 0、or NaN、or などの場合もありますObject.prototype.hasOwnProperty.call(p, someKey)。プロパティが存在するかどうかを確認するには、引き続きを使用する必要があります。
Object.create(null)た場合のみ。私はそのような仮定をしないことを好みます。たとえそれが使用されたことが完全に正しいとしてもObject.create(null)、コードは変更される可能性があり、オブジェクトはObjectある時点で継承するものに置き換えられる可能性があります。hasOwnProperty常に動作します。
{}はObject.create(null)、さらに大きなバグが発生する可能性があります。マイナーな最適化としてObject.create(null)を使用している人しか見ることができません。
!!p[key]はでうまく機能しObject.create(null)ます。しかしhasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)、悪くはありません
pすべてのメソッドが挿入されて安全でなくなる可能性があるため、でメソッドを使用することはできません。
を使用{}してオブジェクトを作成すると、プロトタイプObject.prototypeから基本関数を継承するObjectプロトタイプのオブジェクトObject.create(null)が作成されます。使用してオブジェクトを作成すると、プロトタイプがnullの空のオブジェクトが作成されます。
誰かがの実装を探している場合はObject.create(null)、それがどのように機能するかを知るだけです。これは__proto__非標準で使用されているため、お勧めしません。
function objectCreateMimic()
{
/*optional parameters: prototype_object, own_properties*/
var P = arguments.length>0?arguments[0]:-1;
var Q = arguments.length>1?arguments[1]:null;
var o = {};
if(P!==null && typeof P === "object")
{
o.__proto__ = P;
}
else if(P===null)
{
o.__proto__ = null;
}
if(Q!==null && typeof Q === "object")
{
for(var key in Q)
{
o[key] = Q[key];
}
}
return o;
}
注:私はこれを好奇心から書きましたが、簡単な言葉でしか書かれていません。たとえば、プロパティ記述子を2番目のオブジェクトから戻りオブジェクトに転送していません。
-1中arguments.length>0?arguments[0]:-1;?
Object、最初の引数が指定されていない場合にプロトタイプが保持されるように、。変数名はここではずっと良いかもしれません。
Object.create(null)でオブジェクトを作成すると、プロトタイプなしでオブジェクトが作成されることになります。ここでnullは、プロトタイプチェーンの終わりを意味します。それでも、{}のようなオブジェクトを作成すると、オブジェクトプロトタイプが追加されます。したがって、これらは2つの異なるオブジェクトであり、1つはプロトタイプあり、もう1つはプロトタイプなしです。
if (someKey in p) {