Object.defineProperty(obj, prop, descriptor)

obj:要定义属性的对象

prop:要定义或修改的属性的名称或 symbol

descriptor:要定义或修改的属性描述符

let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    value: 18
})

通过 Object.defineProperty()添加的属性默认是不可以被枚举的,不可修改和不可删除的。

Object.keys (obj):传入一个对象作为参数,返回的是对象里所有属性的属性名作为一个数组。

验证通过 Object.defineProperty()添加的属性是不可以被枚举的

let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    value: 18
})
console.log(Object.keys(person))

打印台只打印出 name 和 sex 两个属性。而通过 Object.defineProperty()添加的 age 没有被枚举出。

如果要想通过 Object.defineProperty()添加的属性可被枚举,则需要添加其他键值对,

let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    value: 18,
    enumerable: true // 控制属性是否可以枚举,默认值是 false
})
console.log(Object.keys(person))

通过 Object.defineProperty()添加的属性默认不可修改

let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    value: 18,
    enumerable: true,
    writable: true // 控制属性是否可被修改,默认值是 false,
    
})
console.log(Object.keys(person))

let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    value: 18,
    enumerable: true,
    writable: true,
    configurable: true // 控制属性是否可以被删除,默认值 false
})
console.log(Object.keys(person))

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。

# Object.defineProperty()的存取描述符。
let number = 18
let person = {
    name: '张三',
    sex: '男'
}
Object.defineProperty(person, 'age', {
    // 当有人读取 person 的 age 属性时,get 函数 (getter) 就会被调用,且返回值就是 age 的值
    get() {
        return number
    },
    // 当有人修改 person 的 age 属性时,set 函数 (setter) 就会被调用,且会收到修改的具体值
    set(value) {
        number = value;
    }
})
console.log(person)