【JavaScript】プロトタイプ上のプロパティをインスタンスで上書き(オーバーライド)させない方法

更新日:2024/06/14

JavaScriptは共通メソッドやプロパティをプロトタイプで提供することがでます。
そしてオブジェクト上に同名のプロパティを作成することで動作の上書きをおこなうことができます。
しかし、上書きをさせたくないケースがあります。
今回は、その場合の対処方法についてお伝えします。

 

方法1:Writable属性をfalseにする

プロトタイプ上のプロパティのWritable属性をfalseにすると、オブジェクトに同名のプロパティを追加できなくなります。

const CF = function(){}
Object.defineProperty( 
  CF.prototype , "func" ,{
    writable:false , // デフォルト値のため省略可能
    value:function(){ console.log("func1") }
  });

const obj = new CF;
obj.func = 200; // TypeError

strictモードの場合、TypeErrorがスローされます。
非strictモードも上書きできませんが、エラーにならずに処理が続行されます。

ただし Object.defineProperty()を使用すると、同名オブジェクトを追加できます。

const obj = new CF;

Object.defineProperty( 
  obj , "func" ,{
    writable:true ,
    value:100
  });
obj.func = 200;
console.log( obj.func ); // 200

禁止になっていませんが、うっかり上書きミスを防止する目的ならこれでいいかもしれません。

 

方法2:オブジェクトを凍結する

二つ目の方法は、オブジェクトを凍結してプロパティ追加を禁止する方法です。

const CF = function(){
  this.prop1 = 100;
  return Object.seal( this );
}
CF.prototype.func = function(){ console.log("func1") };

const obj = new CF;
obj.func = 100; // TypeError

class構文でも同じように記述できます。

const class1 = class {
  constructor(){
    this.prop1 = 100;
    return Object.seal( this );
  }
  func(){ console.log("func1") }
};

const obj = new class1;

obj.func = 100;

問題は他のプロパティも追加できない点ですが、プロトタイプの上書きを気にするような場面で後からプロパティ追加を行うような設計をしないはず…

設計と言う点では、上記のコードは freeze()でプロパティ値の変更も不可にして、値の出し入れはセッターとゲッターを定義した方がよさそうです。

 

方法3:Proxyを使用する

3つめの方法は、Proxyオブジェクトを使用する方法です。

const CF = function(){
  const nameList = ["func"];

  return new Proxy( this , {
    set:function ( target, property , value , receiver ){
        if( nameList.indexOf(property) >= 0 ) 
            throw new TypeError( `"${property}"は上書きできません` );
        return Reflect.set( ...arguments );
    }
  });
}


const obj = new CF;

obj.func = 200; // TypeError: "func"は上書きできません

コンストラクター内でthis値をProxyオブジェクトでラップして返しています。
問題はプロパティアクセスのたびに上記の関数が呼び出されるので、効率があまりよくない点です。
どうしてもこの方法でなければダメ、というケース以外は使わないかな…

更新日:2024/06/14

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。