JavaScriptのプロトタイプチェーンを理解する

  • Home
  • Là Gì_8
  • JavaScriptのプロトタイプチェーンを理解する
2月 14, 2025

JavaScriptでは、関数はプロパティを持つことができます。すべての関数はprototypeという特別なプロパティを持っています。

function doSomething() {} 
console.log(doSomething.prototype); 
// JavaScriptの関数は常にデフォルトのプロトタイププロパティを持ちます
// 例外: アロー関数はデフォルトのプロトタイププロパティを持ちません
const doSomethingFromArrowFunction = () => {}; 
console.log(doSomethingFromArrowFunction.prototype); 

doSomething()はデフォルトのprototypeプロパティを持っています。上記のコードを実行すると、コンソールには次のようなオブジェクトが表示されます。

{ constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

注意: Chromeコンソールはオブジェクトのプロトタイプを表すために[[Prototype]]を使用しますが、これは仕様書の用語です。Firefoxは.prototypeを使用します。統一性を持たせるために、ここでは[[Prototype]]を使用します。

doSomething()のプロトタイプにプロパティを追加することができます。

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
console.log(doSomething.prototype); 

結果:

{ foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

new演算子を使用して、このプロトタイプに基づいてdoSomething()のインスタンスを作成します。new演算子で関数を呼び出すと、その関数のインスタンスであるオブジェクトが返されます。その後、このオブジェクトにプロパティを追加することができます。

function doSomething() {} 
doSomething.prototype.foo = "bar"; // プロトタイプにプロパティを追加
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; // オブジェクトにプロパティを追加
console.log(doSomeInstancing); 

結果:

{ prop: "some value", [[Prototype]]: { foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } } 

doSomeInstancing[[Prototype]]doSomething.prototypeです。doSomeInstancingのプロパティにアクセスすると、ランタイムはまずdoSomeInstancingにそのプロパティがあるかどうかを確認します。

ない場合、ランタイムはdoSomeInstancing.[[Prototype]](つまりdoSomething.prototype)でプロパティを検索します。doSomeInstancing.[[Prototype]]に探しているプロパティがあれば、そのプロパティが使用されます。

ない場合、doSomeInstancing.[[Prototype]].[[Prototype]]がチェックされます。デフォルトでは、任意の関数のprototypeプロパティの[[Prototype]]Object.prototypeです。そのため、doSomeInstancing.[[Prototype]].[[Prototype]](つまりdoSomething.prototype.[[Prototype]]またはObject.prototype)が検索されます。このプロセスはプロトタイプチェーンと呼ばれます。

プロパティがdoSomeInstancing.[[Prototype]].[[Prototype]]で見つからない場合、doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]]が検索されます。しかし、Object.prototype.[[Prototype]]nullなので、doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]]は存在しません。プロトタイプチェーン全体が検索された後、ランタイムはプロパティが存在しないと判断し、プロパティの値はundefinedになります。

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; 
console.log("doSomeInstancing.prop: ", doSomeInstancing.prop); 
console.log("doSomeInstancing.foo: ", doSomeInstancing.foo); 
console.log("doSomething.prop: ", doSomething.prop); 
console.log("doSomething.foo: ", doSomething.foo); 
console.log("doSomething.prototype.prop:", doSomething.prototype.prop); 
console.log("doSomething.prototype.foo: ", doSomething.prototype.foo); 

結果:


doSomeInstancing.prop: some value
doSomeInstancing.foo: bar
doSomething.prop: undefined
doSomething.foo: undefined
doSomething.prototype.prop: undefined
doSomething.prototype.foo: bar

Leave A Comment

Create your account