이 글은 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!