>  기사  >  웹 프론트엔드  >  JS의 Object.defineProperty 사용법 소개(코드 예)

JS의 Object.defineProperty 사용법 소개(코드 예)

不言
不言앞으로
2019-03-15 17:12:212376검색

이 글은 JS에서 Object.defineProperty의 사용법을 소개합니다.(코드 예제) 여기에는 특정 참조 값이 있습니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

JavaScript에서는 다음 메서드를 통해 개체의 속성을 추가하거나 수정하는 경우가 많습니다.

obj.name = 'John'

또한 Object.defineProperty() 메서드를 통해 개체의 속성을 추가하거나 수정할 수도 있습니다. 더 중요한 것은 대상 객체 obj 및 속성 이름 prop 외에도 메서드가 속성 설명자를 전달하여 더 복잡한 속성을 얻을 수 있다는 것입니다. 속성 설명자는 두 가지 형태로 제공되는 개체입니다. 하나는 데이터 설명자이고 다른 하나는 액세스 설명자입니다.

Object.defineProperty(obj, prop, descriptor)

데이터 설명자

데이터 설명자는 다음 기능을 지원합니다.

enumerable: 개체를 열거할 수 있는지 여부를 나타냅니다. 기본값은 false입니다. 이는 열거할 수 없음을 의미합니다. for...in 및 Object.keys()에서 열거할 수 없으며 JSON.stringify()에도 영향을 미칩니다.

configurable: 객체 속성을 삭제할 수 있는지 여부와 값 및 쓰기 가능 속성을 제외한 다른 속성을 수정할 수 있는지 여부를 나타냅니다. 기본값은 false입니다. 이는 속성을 삭제할 수 없고 특성을 수정할 수 없음을 의미합니다.

값: 속성에 해당하는 값, 기본값은 정의되지 않습니다.

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

저장소 설명자

저장소 설명자는 다음 기능을 지원합니다.

열거 가능: 위와 동일합니다.

구성 가능: 위와 동일합니다.

set: setter 메소드를 설정합니다. 속성이 수정되면 이 메소드는 새 속성 값을 매개변수로 실행됩니다. 기본값은 정의되지 않습니다.

get: 속성에 액세스할 때 실행될 getter 메서드를 설정합니다. 기본값은 정의되지 않습니다.

// 示例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

Notes

또한 세 가지 주의할 점이 있습니다. 첫째, 두 개의 서로 다른 설명자가 있는 속성은 공유할 수 없습니다. 둘째, 속성을 추가할 때 전달되지 않은 속성은 기본값으로 설정됩니다. 속성을 수정하면 전달되지 않은 속성은 기본값으로 설정됩니다. 입력된 특성은 동일하게 유지됩니다. 세 번째는 다음과 같습니다.

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
})

실용 적용

예를 들어 두 가지 속성을 가진 개체 Student가 있습니다. : 이름과 나이. 나이를 너무 크거나 작게 설정하지 않으려면 어떻게 해야 하나요? 나이를 수정하고 싶을 때마다 setter 메소드를 통해 속성을 수정하고 getter 메소드를 통해 속성을 읽을 수 있습니다.

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 메서드는 많은 코드만 추가합니다. 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제