Object.defineProperty()メソッドの簡単な理解

オブジェクトを理解する

オブジェクトを作成すると、いくつかのプロパティとメソッドがオブジェクトに追加されます。これらのプロパティは、いくつかの特性値を使用して作成されます。JavaScriptは、これらの特性値を使用して動作を定義します。

属性タイプ

ECMA-261は、JavaScriptエンジンを実装するためにこれらの機能を定義しているため、Jsで直接アクセスすることはできません。機能の内部値を示すために、仕様では2組の角括弧で囲んでいます。たとえば、[[Enumerable] ]
ECMAScript属性には、データ属性とアクセス属性の2種類があります。

データ属性

data属性には、値の読み取りと書き込みが可能なデータ値の位置が含まれます。data属性には、その動作を説明する4つの特性があります。

  • [[構成可能]]:属性を再定義するために削除によって属性を削除できるかどうか、属性の特性を変更できるかどうか、または属性値をアクセサー属性に変更できるかどうかを示します。デフォルトはtrueです。
  • [[Enumerable]]:for-inループを介して属性を返すことができます。デフォルトはtrueです。
  • [[書き込み可能]]:属性の値を変更できるかどうかを示します。デフォルトはtrueです。
  • [[値]]:この属性のデータ値が含まれます。プロパティ値を読み取るときは、この場所から読み取ります。プロパティ値を書き込むときは、新しい値をこの場所に保存します。デフォルト値は未定義
    です。たとえば、オブジェクトを作成してプロパティ値を追加します。
const person = {
  name: 'poppy'
}

nameという名前の属性がここに作成され、彼に指定された値は「poppy」です。これは、[[Value]]機能が「poppy」に設定され、他の3つの機能がtrueに設定されることを意味します。

Object.defineProperty()

プロパティのデフォルトプロパティを変更するには、ECMAScript5のObject.defineProperty()メソッドを使用する必要があります。このメソッドは、プロパティが配置されているオブジェクト、オブジェクトの名前、および記述子
オブジェクトの3つのパラメーターを受け取ります。記述子のプロパティオブジェクトは、構成可能、列挙可能、書き込み可能、​​および値である必要があります。1つ以上の値を設定し、対応する属性値を変更できます

  • 人の読み取り専用の名前属性を作成する
let person = {
    
    }
Object.defineProperty(person,"name",{
    
    
  writable: false,
  value: "poppy"
})
console.log(person.name) // poppy
person.name = "yaping"
console.log(person.name) // poppy
// 当修改只读属性name的时候,非严格模式会忽略赋值操作,严格模式下会抛出异常
  • 構成可能をfalseに設定し、属性をオブジェクトから削除できないことを示します
let person = {
    
    }
Object.defineProperty(person,"name",{
    
    
  configurable: false,
  value: 'poppy'
})
// 如果对name属性调用delete,在非严格模式会被忽略操作,严格模式会抛出异常
// 这里需要注意,一旦把属性定义为不可配置,就不能再把它变回可配置。此时,再次调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误
// 抛出错误
Object.defineProperty(person,"name",{
    
    
  configurable: true,
  value: 'poppy'
})
  • Object.defineProperty()メソッドを呼び出すとき、指定されていない場合、構成可能、列挙可能、および書き込み可能なプロパティのデフォルト値はすべてfalseです。ほとんどの場合、Object.defineProperty()メソッドによって提供される高度な機能を使用する必要はありませんが、これらの概念を理解することはJavaScriptオブジェクトにとって非常に役立ちます。

IE8は、Object.defineProperty()メソッドを実装する最初のブラウザーバージョンです。ただし、このバージョンには多くの制限があります。このメソッドはDOMオブジェクトでのみ使用でき、アクセサープロパティのみを作成できます。実装が不完全なため、IE8ではObject.defineProperty()メソッドを使用しないことをお勧めします。

アクセサのプロパティ

アクセサプロパティにはデータ値は含まれていません。ゲッター関数とセッター関数のペアが含まれています(ただし、これらの関数はどちらも必要ありません)。アクセサプロパティを読み取るときは、有効な値を返す責任があるgetter関数が呼び出されます。アクセサプロパティを書き込むときは、setter関数が呼び出され、新しい値が渡されます。この関数は、データの処理方法を担当します。アクセサーには次の4つの特徴があります

  • [[構成可能]]:プロパティを削除してプロパティを再定義できるかどうか、プロパティのプロパティを変更できるかどうか、またはプロパティをデータプロパティとして変更できるかどうかを示します。オブジェクトに直接定義されているプロパティの場合、このプロパティデフォルトはtrue
  • [[Enumerable]]:属性がfor-inループを介して返されるかどうかを示します。デフォルトはtrueです。
  • [[Get]]:プロパティ値を読み取るときに呼び出される関数。デフォルト値は未定義です。
  • [[設定]]:プロパティ値を書き込むときに呼び出される関数。デフォルト値は未定義です。

Object.defineProperty()

アクセサプロパティは直接定義できません。Object.defineProperty()を使用して定義する必要があります。

  • アクセサ属性を使用して属性の値を設定する一般的な使用法では、他の属性が変更されます。
    次のコードは、オブジェクトブックを作成し、_yearとeditionの2つのデフォルト属性を定義します。_yearの前の下線は、プロパティがオブジェクトメソッドを介してのみアクセスできることを示すために一般的に使用される記号であり、アクセサープロパティyearにはgetter関数とsetter関数が含まれています。ゲッターは_yearの値を返し、セッターは計算を使用して正しいバージョンを確認します。したがって、year属性を2005に変更すると、_yearは2005をプログラムし、エディションは2になります。
let book = {
    
    
  _year: 2004,
  edition: 1
}
Object.defineProperty(book,"year",{
    
    
  get: function(){
    
    
    return this._year
  },
  set: function(newValue){
    
    
    if(newValue > 2004){
    
    
        this._year = newValue
        this.edition += newValue - 2004
    }
  }
})
book.year = 2005
console.log(book.edition) // 2

おすすめ

転載: blog.csdn.net/qq_39045755/article/details/113183894