__proto__とprototypeの違い

2024-04-13

JavaScriptにおける protoprototype の詳細比較

proto とは?

proto は、オブジェクトのプロトタイプチェーンの次のオブジェクトへの直接参照です。つまり、あるオブジェクトがプロパティやメソッドにアクセスできない場合、proto によって参照される別のオブジェクトから継承しようとする仕組みです。

例:

function Person(name) {
  this.name = name;
}

const person = new Person('Alice');

console.log(person.__proto__); // { name: 'Alice', constructor: Person }

この例では、person.__proto__Person.prototype を参照します。つまり、person オブジェクトは name プロパティと constructor プロパティを Person.prototype から継承していることを意味します。

prototype は、コンストラクター関数によって作成されたすべてのオブジェクトが継承するプロパティとメソッドのセットを定義するオブジェクトです。つまり、prototype は、そのコンストラクターで生成されたすべてのオブジェクトのプロトタイプチェーンの最上位に位置します。

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('Alice');

person.greet(); // Hello, my name is Alice

この例では、Person.prototypegreet メソッドが定義されています。person オブジェクトは greet メソッドを直接持っていませんが、prototype チェーンを辿ることで Person.prototype から継承し、greet メソッドを呼び出すことができます。

proto と prototype の違い

項目protoprototype
定義オブジェクトのプロトタイプチェーンの次のオブジェクトへの直接参照コンストラクター関数によって作成されたすべてのオブジェクトが継承するプロパティとメソッドのセットを定義するオブジェクト
アクセス方法オブジェクトインスタンスに対して __proto__ プロパティでアクセスコンストラクター関数に対して .prototype プロパティでアクセス
変更可能性個々のオブジェクトインスタンスに対して変更可能コンストラクター関数に対してのみ変更可能
継承個々のオブジェクトインスタンスに対して継承コンストラクターで生成されたすべてのオブジェクトに対して継承
  • proto は個々のオブジェクトのプロトタイプチェーンにおける次のオブジェクトへの参照であり、変更可能です。

補足

  • 新しい JavaScript エンジンでは、proto は非推奨となり、代わりに Object.getPrototypeOf()Object.setPrototypeOf() メソッドを使用することが推奨されています。



JavaScriptにおける protoprototype の理解を深めるためのサンプルコード

基本的な動作

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('Alice');
console.log(person.__proto__); // { name: 'Alice', constructor: Person }
console.log(Person.prototype); // { constructor: Person, greet: ƒ }
person.greet(); // Hello, my name is Alice

解説:

  • このコードでは、Person コンストラクター関数と、その prototype オブジェクトに greet メソッドを定義しています。
  • person インスタンスは Person.prototype から greet メソッドを継承し、呼び出すことができます。
  • person.__proto__Person.prototype を参照していることを確認できます。
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('Alice');
person.__proto__ = {
  greet: function() {
    console.log('Hi there!');
  }
};

person.greet(); // Hi there!
  • このコードでは、person インスタンスの __proto__ を別のオブジェクトに変更しています。
  • その結果、person.greet は元の Person.prototype.greet ではなく、新しく設定されたメソッドが呼び出されます。
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('Alice');

Person.prototype.greet = function() {
  console.log('Hello, everyone!');
};

person.greet(); // Hello, everyone!
  • このコードでは、Person.prototype.greet メソッドを直接変更しています。
  • その結果、person インスタンスを含む、そのコンストラクターで生成されたすべてのオブジェクトgreet メソッドが変更されます。

Object.create() を使ったオブジェクトの作成

const personProto = {
  greet: function() {
    console.log('Hello from prototype!');
  }
};

const person = Object.create(personProto);
person.name = 'Alice';

console.log(person.__proto__); // { greet: ƒ }
console.log(person.greet()); // Hello from prototype!
  • このコードでは、Object.create() メソッドを使って、personProto オブジェクトをプロトタイプとする person オブジェクトを作成しています。
  • person オブジェクトは greet メソッドを personProto から継承し、呼び出すことができます。



ビジュアルツール

これらのツールは、オブジェクトのプロトタイプチェーンと、protoprototype がどのように関係しているのかを視覚的に表現することができます。

インタラクティブなチュートリアル

これらのチュートリアルは、protoprototype の基本的な概念から、より高度な使用方法まで、段階的に学ぶことができます。

これらの書籍は、protoprototype の理論的な説明だけでなく、実際のコード例も豊富に掲載されています。

これらのフォーラムやコミュニティには、protoprototype に関する豊富な情報と、経験豊富な開発者からの回答が揃っています。


javascript prototype javascript-objects


jQueryのdelay()とclearQueue()でwindow.setTimeout()をキャンセルする方法

この解説では、JavaScript と jQuery を使って、window. setTimeout() をキャンセルする方法を分かりやすく説明します。clearTimeout() 関数は、window. setTimeout() で生成されたタイマーをキャンセルするために使用します。setTimeout() の返り値であるタイマーIDを clearTimeout() に渡すことで、そのタイマーを無効化できます。...


【保存版】JavaScriptで浮動小数点数をカンマ区切りで表示する方法と、それ以外の高度なフォーマット技

toFixed() 関数は、指定された桁数まで小数点以下の数字を丸め、文字列に変換します。最もシンプルで使いやすいフォーマット方法の一つです。利点:シンプルで分かりやすいコードが簡潔で書きやすい多くの場合で十分なフォーマット機能を提供注意点:...


jQueryとJavaScriptとCSSにおける要素の絶対座標取得方法の比較

offset() メソッドは、要素の左上隅がドキュメントの左上隅からのオフセット(距離)を取得します。offset() メソッドは、要素がスクロールによって移動しても、常に正しい座標を取得することができます。position() メソッドは、要素がスクロールによって移動しても、親要素に対する相対的な座標は変わりません。...


jQueryのイベントリスナー:動的に追加された要素にもバッチリ対応!

on()メソッドは、イベントリスナーを追加するための最も一般的な方法です。以下のコードのように、イベント名、セレクター、イベントハンドラ関数を指定して使用します。このコードでは、.my-buttonクラスを持つ要素がクリックされたときに、イベントハンドラー関数が実行されます。イベントハンドラー関数は、動的に追加された要素を含むすべての要素に対して実行されます。...


JavaScript:配列操作の基本「unshiftとsplice」で先頭に要素を挿入

JavaScriptには、配列の先頭に要素を挿入するための便利なメソッドが用意されています。 主に以下の2つの方法があります。unshift() メソッドは、配列の先頭に1つ以上の要素を挿入するために使用されます。 メソッドの引数として挿入する要素を指定し、挿入後の配列の長さを返します。...