初心者でも分かるprototypeとthisを使いこなすための3つのポイント

2024-04-08

JavaScriptにおける「prototype」と「this」の使い分け

オブジェクトのプロトタイプ

prototypeは、オブジェクトの設計図のようなものです。オブジェクトに共通するプロパティやメソッドを定義します。

例:

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

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

const person1 = new Person('John');
const person2 = new Person('Mary');

person1.sayHello(); // Hello, my name is John.
person2.sayHello(); // Hello, my name is Mary.

この例では、Personというコンストラクタ関数を定義し、nameプロパティとsayHelloメソッドをプロトタイプに定義しています。new演算子を使ってPerson関数を呼び出すと、新しいオブジェクトが作成され、プロトタイプからプロパティとメソッドが継承されます。

this キーワード

thisキーワードは、現在実行中のコードのコンテキストを表します。オブジェクト指向プログラミングでは、メソッド内で使用されることが多いです。

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

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

const person1 = new Person('John');

person1.sayHello(); // Hello, my name is John.

この例では、sayHelloメソッド内のthisは、person1オブジェクトを指します。つまり、this.nameperson1.nameと同じ意味になります。

prototypeとthisの使い分け

prototypeは、オブジェクト作成時に共通するプロパティやメソッドを定義するために使用します。一方、thisは、メソッド内でオブジェクトの状態を参照するために使用します。

  • this: メソッド内でのオブジェクトへの参照。



プロトタイプを使ったサンプルコード

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

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

const person1 = new Person('John');
const person2 = new Person('Mary');

person1.sayHello(); // Hello, my name is John.
person2.sayHello(); // Hello, my name is Mary.

// プロトタイプに直接アクセスしてプロパティを追加
Person.prototype.age = 20;

console.log(person1.age); // 20
console.log(person2.age); // 20

// 個別にプロパティを追加
person1.age = 30;

console.log(person1.age); // 30
console.log(person2.age); // 20
  • new演算子を使ってPerson関数を呼び出すと、新しいオブジェクトが作成され、プロトタイプからプロパティとメソッドが継承されます。
  • プロトタイプに直接アクセスしてプロパティを追加すると、すべてのPersonオブジェクトにそのプロパティが追加されます。
  • 個別にプロパティを追加すると、そのオブジェクトのみにそのプロパティが追加されます。

this キーワードを使ったサンプルコード

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

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

  this.introduce = function() {
    console.log(`I am ${this.name}, and I am ${this.age} years old.`);
  };
}

const person1 = new Person('John');
person1.age = 30;

person1.sayHello(); // Hello, my name is John.
person1.introduce(); // I am John, and I am 30 years old.

const person2 = new Person('Mary');
person2.age = 25;

person2.sayHello(); // Hello, my name is Mary.
person2.introduce(); // I am Mary, and I am 25 years old.

このコードでは、Personコンストラクタ関数のsayHelloメソッドとintroduceメソッド内でthisキーワードを使用しています。

  • this.nameは、現在実行中のオブジェクトnameプロパティを参照します。
  • メソッド内でthisキーワードを使用することで、オブジェクトの状態を動的に参照することができます。



prototypeとthis以外の方法

クラス

JavaScriptでは、classキーワードを使ってクラスを定義することができます。クラスは、プロパティやメソッドをカプセル化し、オブジェクト指向プログラミングをより簡単に実装できます。

class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

const person1 = new Person('John');
const person2 = new Person('Mary');

person1.sayHello(); // Hello, my name is John.
person2.sayHello(); // Hello, my name is Mary.

ES6モジュールを使うと、オブジェクト指向プログラミングのコードをよりモジュール化することができます。

// person.js
export class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

// main.js
import { Person } from './person.js';

const person1 = new Person('John');
const person2 = new Person('Mary');

person1.sayHello(); // Hello, my name is John.
person2.sayHello(); // Hello, my name is Mary.

ファクトリー関数を使うと、オブジェクトを生成するためのコードを再利用することができます。

function createPerson(name) {
  return {
    name,
    sayHello() {
      console.log(`Hello, my name is ${this.name}.`);
    },
  };
}

const person1 = createPerson('John');
const person2 = createPerson('Mary');

person1.sayHello(); // Hello, my name is John.
person2.sayHello(); // Hello, my name is Mary.

これらの方法は、それぞれ異なる利点と欠点があります。どの方法を使うのが最適かは、状況によって異なります。


javascript prototype this


コードの可読性とパフォーマンスを両立:JavaScriptにおけるカリー化のベストプラクティス

カリー化は、クロージャという技術を利用して実現されます。クロージャは、関数内に関数定義を持ち、外部変数を参照できる特殊な関数です。カリー化を行うと、元の関数は部分適用関数と呼ばれる新しい関数群に変換されます。部分適用関数は、元の関数の引数を一部固定した状態で呼び出せる関数です。...


JavaScriptのデバッグに役立つ!console.log()とdebuggerを使いこなす

最もよく使われる方法は、console. log() 関数です。console. log() は、任意の式やオブジェクトを渡すと、コンソールにその値を出力します。console. log() は、オブジェクトや配列の中身も展開して表示することができます。...


for...in、Object.keys、forEach... あなたに最適な方法は?

最も基本的な方法は、for. ..in ループを使用する方法です。このコードは、obj オブジェクトのすべてのプロパティを反復処理し、プロパティ名と値を出力します。注意点for. ..in ループは、オブジェクト自身のプロパティだけでなく、プロトタイプチェーンから継承されたプロパティもすべて反復処理します。...


SVG要素のz-indexを自由自在に操る:描画順序、svgZOrderライブラリ、clipPath、mask、filter徹底解説

SVG(Scalable Vector Graphics)は、Webブラウザ上でベクター画像をレンダリングするための汎用的なフォーマットです。HTMLドキュメント内に埋め込むことができ、高いスケーラビリティと柔軟性を備えています。しかし、SVG要素においては、CSSのz-indexプロパティを用いて要素の重ね順を制御することができません。これは、SVGがHTMLとは異なるXMLベースの形式であり、独自のレンダリングエンジンを持つためです。...


Vanilla JS のメリットとデメリット

Vanilla JS とは、ライブラリやフレームワークを一切使用せずに記述する JavaScript のことを指します。つまり、ネイティブな JavaScript API のみを使用して開発を行うということです。Vanilla JS は、軽量で高速であるという利点があります。また、シンプルで分かりやすい コードとなるため、初心者でも比較的学習しやすいという特徴もあります。...