Categories: JavaScript

【JavaScript入門】プロトタイプベース

プロトタイプ

プロトタイプの作成方法

プロトタイプでクラスを作成するには以下のように記述します。

js

//Personクラス
let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

インスタンス化

作成したプロトタイプを基にインスタンス化するには以下のように記述します。

js

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
console.log(p1.getName());//Taro

let p2 = new Person('Jiro', 10);
console.log(p2.getName());//Jiro

インスタンス化したオブジェクトにメソッドを追加する。

JavaScriptでは、new演算子で初期化済みのオブジェクトに対して、後からメソッドを追加することが出来ます。
以下の例ではp1インスタンスにgetAgeメソッドを追加しています。getAgeメソッドを実行できるのはp1インスタンスのみで、p2インスタンスでは実行することはできません。

js

//Personクラス
let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 10);

//p1インスタンスにgetAgeメソッドを追加
p1.getAge = function(){
    return this.age;
}

//getAgeメソッドの実行
console.log(p1.getAge());//10
console.log(p2.getAge());//実行時にエラー(p2.getAge is not a function)

以下のように、インスタンス化したオブジェクトに対してインスタンスオブジェクト名.prototype.メソッド名のようにメソッドを追加することはできません。

js

//以下のような記述はできない。
p1.prototype.getAge = function(){
    return this.age;
}

プロトタイプベースのオブジェクト指向では、このように生成したあとにメソッドやプロパティを追加することができるため、同一クラスを元に生成されたインスタンスであっても、それぞれが持つメンバが同一だとは限らないのです。 これを解消するには以下のようにprototypeオブジェクトに対してメソッドを追加するようにする必要があります。

prototypeオブジェクトに対してメソッドを追加する

すべてのインスタンスに対して共通のメソッドを追加したい場合は、大元のPersonオブジェクトに対してメソッドを追加します。

js

let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 5);

//PersonクラスにgetAgeメソッドを追加
Person.prototype.getAge = function(){
    return this.age;
}

//getAgeメソッドの実行
console.log(p1.getAge());//10
console.log(p2.getAge());//5

prototypeオブジェクトに対してプロパティ(変数)を追加する

同様に、すべてのインスタンスに対して共通のプロパティ(変数)を追加したい場合は、大元のPersonオブジェクトに対して追加します。

js

let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 5);

//Personクラスにプロパティを追加
Person.prototype.sex = '男性';

//性別を出力
console.log(p1.sex);//男性
console.log(p2.sex);//男性

//p2のみ性別を変更
p2.sex = '女性';

//性別を出力
console.log(p1.sex);//男性
console.log(p2.sex);//女性

prototypeオブジェクトからプロパティ(変数)を削除する

delete演算子を用いてプロトタイプオブジェクト名.prototype.プロパティ名と記述します。

js

let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 5);

//Personクラスにプロパティを追加
Person.prototype.sex = '男性';

//性別を出力
console.log(p1.sex);//男性
console.log(p2.sex);//男性

//プロパティを削除
delete Person.prototype.sex;

//性別を出力
console.log(p1.sex);//undefined
console.log(p2.sex);//undefined

オブジェクトリテラルを使って一括でメソッドやプロパティを追加する

以下のようにオブジェクトリテラルを使うことでメソッドやプロパティをまとめて追加することができます。

js

//Personクラスにプロパティを追加
Person.prototype = {
    getName:function(){
        return this.name;
    },

    sex:'男性'
}

以下はサンプルです。

js

let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
}

//Personクラスにプロパティを追加
Person.prototype = {
    getName:function(){
        return this.name;
    },

    sex:'男性'
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 5);


//名前を出力
console.log(p1.getName());//Taro
console.log(p2.getName());//Jiro

//性別を出力
console.log(p1.sex);//男性
console.log(p2.sex);//男性

インスタンス化したオブジェクトに後からメソッドやプロパティを追加されないようにする方法seal()

Object.seal(this);とすることで、後からメソッドやプロパティが追加されることを防ぎます。
メソッドを追加する処理は正常に通ってしまいますが、呼び出し時にエラーになります。

js

//Personクラス
let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
    Object.seal(this);//←これを追加する。
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 10);

//p1インスタンスにgetAgeメソッドを追加
p1.getAge = function(){
    return this.age;
}

//getAgeメソッドの実行
console.log(p1.getAge());//実行時エラー(p1.getAge is not a function)

インスタンスに対する追加を防ぐだけなので、以下のようにprototypeそのものに追加することは可能です。

js

//Personクラス
let Person = function(name,age){
    this.name = name;
    this.age = age;
    this.getName = function (){
        return this.name;
    }
    Object.seal(this);//←これを追加する。
}

//Personクラスをインスタンス化
let p1 = new Person('Taro', 10);
let p2 = new Person('Jiro', 10);

//PersonクラスにgetAgeメソッドを追加
Person.prototype.getAge = function(){
    return this.age;
}

//getAgeメソッドの実行
console.log(p1.getAge());//10

以上で記事の解説はお終い!

HTML、CSS、JavaScriptをもっと勉強したい方にはUdemyがオススメ!同僚に差をつけよう!

issiki_wp