defineProperty和defineProperties方法的使用

82 阅读2分钟

defineProperty

基本语法

使用方法:Object.defineProperty(对象名,'属性名',描述对象)

描述对象的属性:

属性名作用
configurable对象的属性是否可以被删除,以及除value和writable特性外的其他特性是否可以被修改
enumerable该属性是否可枚举
writable该属性是否可修改
value该属性的值或者方法
get设置该属性值时调用该函数
set该属性的值或者方法

声明方式1

let obj = {name: 'zb'}
// 默认描述对象的configurable,enumerable,writable为true
obj.name = 'zbzb'
console.log(obj.name);  //zbzb

声明方式2

let obj = {}
Object.defineProperty(obj,'name',{
    value: 'zb',
    // 默认描述对象的configurable,enumerable,writable为false
})
console.log(obj)       // {},这里显示空对象,因为enumerable为false,不可枚举
console.log(obj.name); // zb
obj.name = 'zbzb'
console.log(obj.name); // 依然zb

writable的作用,该属性是否可修改

let obj = {}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    // 默认描述对象的configurable,enumerable为false
})
console.log(obj.name); // zb
obj.name = 'zbzb'
console.log(obj.name); // zbzb

enumerable的作用,该属性是否可枚举

最一开始一直以为是说该属性为数组或对象时,能不能把该属性中的元素遍历出来。后来发现这种想法是错的,是否枚举说的是在遍历或者查看对象时是否显示该属性。

let obj = {age: 18, sex: '男'}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: false,               // 为false,不能被遍历出
    // configurable默认为false
})
console.log(obj);                    // { age: 18, sex: '男' }没有name
for(let item in obj){
    console.log(item);               // age和sex,没有name
}

configurable的作用,对象的属性是否可以被删除,以及除value和writable特性外的其他特性是否可以被修改

let obj = {age:18}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: false,
    configurable: true            // 为true,则可以删除
})
console.log(obj.name);            // zb
delete obj.name
console.log(obj.name);            // undefined



let obj = {age:18}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: false,
    configurable: false        //为false,则不可删除
})
console.log(obj.name);         //zb
delete obj.name
console.log(obj.name);         //依然zb

let obj = {age:18}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: false,
    configurable: false        //为false,则不可修改
})
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: true,          //改为true,会报错
    configurable: false
})




let obj = {age:18}
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: false,
    configurable: true        //为true,则可修改
})
Object.defineProperty(obj,'name',{
    value: 'zb',
    writable: true,
    enumerable: true,          //改为true,不会报错
    configurable: false
})

set和get的作用

(set,get)和(value,writable)冲突,不可同时存在,否则会报错。

get函数必须要把新值return出来,否则结果为undefined

如果方法中调用该属性,使用方式this._属性名。使用其他函数的方式this.属性名

let person = { age: '18' }
Object.defineProperty(person, 'sex',{
    value: '男'
})
Object.defineProperty(person, 'name', {
    set(newVal){
        this._name = 'firstName--' + newVal + '--' + this.age + '--' + this.sex
    },
    get(){
        return this._name           // 必须要有return返回值
    }
})
person.name = 'zb'                  // 走set函数
console.log(person.name);           // 走get函数,结果为'firstName--zb--18--男'

defineProperties

根据这个方法的名字我们就可以看出,这个方法是设置多个属性的,它除了可以一次设置多个属性以外,和defineProperty方法基本没什么区别。

let person = {}
Object.defineProperties(person, {
    'name': {
        value: 'zb'
    },
    'age': {
        value: '18',
        writable: 'false'
    }
})
console.log(person.age,person.name);  // 18 zb