【8/27まで】Udemyの人気コースが今なら1,200円から!!

【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オブジェクトに対してメソッドを追加するようにする必要があります。

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クラスにgetAgeメソッドを追加
Person.prototype.getAge = function(){
    return this.age;
}

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

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);//男性

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

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

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

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です