ホームページ  >  記事  >  ウェブフロントエンド  >  JS での Object.defineProperty の使用法の概要 (コード例)

JS での Object.defineProperty の使用法の概要 (コード例)

不言
不言転載
2019-03-15 17:12:212365ブラウズ

この記事では、JS での Object.defineProperty の使用法 (コード例) を紹介します。一定の参考価値があります。必要な友人はそれを参照できます。お役に立てば幸いです。

JavaScript では、オブジェクトのプロパティは、次のメソッドを通じて追加または変更されることがよくあります:

obj.name = 'John'

さらに、オブジェクトのプロパティは、Object.defineProperty を通じて追加または変更することもできます。 () 方法 。さらに重要なのは、ターゲット オブジェクト obj とプロパティ名 prop に加えて、メソッドはプロパティ記述子 descriptor を渡して、より複雑なプロパティを実現できることです。属性記述子はオブジェクトであり、2 つの形式があります。1 つはデータ記述子、もう 1 つはアクセス記述子です。

Object.defineProperty(obj, prop, descriptor)

データ記述子

データ記述子は、次の機能をサポートします。

enumerable: オブジェクトが列挙できるかどうかを示します。デフォルトは false で、列挙できないことを意味します。このプロパティは for...in および Object.keys() で列挙できず、JSON.stringify() にも影響します。

configurable: オブジェクト属性を削除できるかどうか、また、値属性と書き込み可能な属性を除く他の属性を変更できるかどうかを示します。デフォルトは false で、属性を削除したり、特性を変更したりできないことを意味します。

value: 属性に対応する値。デフォルトは未定義です。

writable: デフォルトは false です。これは、読み取り専用であり、このプロパティに値を割り当てることができないことを意味します。厳密モードでは、読み取り専用プロパティに値を割り当てるとエラーが発生します。リラックス モードでは、読み取り専用プロパティへの値の割り当ては有効になりません。

// 示例1,等同于 obj.name = 'John'
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: true
})

// 示例2,将 name 属性设置为只读
'use strict'
var obj = {}
Object.defineProperty(obj, 'name', {
  value: 'John',
  writable: false,
  configerable: true,
  enumerable: true
})
obj.name = 'Joy'  // TypeError

// 示例3,将 name 属性设置为不可枚举
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: false
})
console.log(obj.name)  // John
console.log(Object.keys(obj))  // []

// 示例4,将 name 属性设置不可配置(不可删除,除value和writable特性外的其它特性不可被修改)
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: false,
  enumerable: true
})
delete obj.name  // false
Object.defineProperty(obj, 'name', { enumerable: false })  // TypeError

ストレージ記述子

ストレージ記述子は次の機能をサポートします:

enumerable: 上記と同じ。

構成可能: 上記と同じ。

set: setter メソッドを設定します。プロパティが変更されると、このメソッドは新しいプロパティ値をパラメータとして実行されます。デフォルト値は未定義です。

get: プロパティにアクセスしたときに実行されるゲッター メソッドを設定します。デフォルト値は未定義です。

// 示例5,使用 get 和 set,计数属性读写的次数
var obj = {}, name = '', count1 = 0, count2 = 0
Object.defineProperty(obj, 'name', { 
  get: function () { 
    console.log('Read ' + (++count1) + ' times')
    return name
  },
  set: function (newVal) {
    console.log('Write ' + (++count2) + ' times')
    name = newVal
  }
})
obj.name  // Read 1 times
obj['name']  // Read 2 times
obj.name = 'Joy'  // Write 1 times
obj.name = 'Jack'  // Write 2 times

注意事項

さらに、2 つの異なる記述子を持つ属性は共有できない、属性を追加すると、導入されていない特性はデフォルト値に設定される、という 3 つの注意点があります。 . 、特性を変更するとき、導入されていない特性は同じままです; 3 番目は次のとおりです:

Object.defineProperty(obj, 'name', { value: 'John' })
// 属性是只读,不可配置,且不可枚举的。等同于
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: false,
  configerable: false,
  enumerable: false
})

obj.name = 'John'
// 属性可写的,可配置的,可枚举的。等同于
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: true
})

実際のアプリケーション

たとえば、2 つの属性を持つオブジェクト Student があります。名前と年齢 希望しない場合 年齢の設定が高すぎる場合、または低すぎる場合はどうすればよいですか?セッター メソッドとゲッター メソッドを追加できます。年齢を変更するたびに、セッター メソッドを通じて属性を変更し、ゲッター メソッドを通じて属性を読み取ることができます:

function Student (name, age) {
  this.name = name
  this.setAge = function (val) { 
    age = val
    if (age < 0) age = 0
    if (age > 100) age = 100
  }
  this.getAge = function () { return age }
}

var s = new Student('John', 16)
s.setAge(25)
console.log(s.getAge())  // 25
s.setAge(-5)
console.log(s.getAge())  // 0
s.setAge(500)
console.log(s.getAge())  // 100

見た目は美しいですが、毎回属性が読み取られるか変更される場合 setter メソッドまたは getter メソッドは 1 回呼び出されるため、多くのコードが追加されます。 Object.defineProperty メソッドを使用すると、追加のコードは必要なく、最も原始的な方法でプロパティを直接読み取り、変更できます:

function Student (name, age) {
  this.name = name
  var _age = age
  Object.defineProperty(this, 'age', {
    get: function () { return _age },
    set: function (val) {
      _age = val
      if (_age < 0) _age = 0
      if (_age > 100) _age = 100
    }
  })
}

var s = new Student('John', 16)
s.age = 25
console.log(s.age)  // 25
s.age = -5
console.log(s.age)  // 0
s.age = 500
console.log(s.age)  // 100

バッチ処理

Object.defineProperties() メソッドバッチで追加または変更できます プロパティ:

var obj = {}
Object.defineProperties(obj, {
  name: { value: 'John', emunerable: true },
  age: { value: 20, emunerable: true }
})

Object.create() メソッドは、オブジェクトの作成時にプロパティをバッチで追加できます:

var obj = Object.create(Object.prototype, {
  name: { value: 'John', emunerable: true },
  age: { value: 20, emunerable: true } 
})

setter プロパティと getter プロパティを含むオブジェクトを作成することもできますリテラル経由:

var obj = {
  get name() {
    return 'John'
  },
  set name(val) {
    console.log(val)
  },
  get age() {
    return 18
  }
}

以上がJS での Object.defineProperty の使用法の概要 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。