JavaScript Object.defineProperty()理解与示例

 以下为示例代码,可根据注释理解代码,详细步骤以后再写.

参考链接: https://www.jianshu.com/p/ce4fbd2c0e23

configurable / enumerable / writable  解释与示例

// 声明一个空对象
var person = {};
// ?  Object.defineProperty
// 1. Object.defineProperty(已声明对象,自定义变量名称,设置参数信息)
// 2. 该方法会在person中声明或修改变量
// 3. 对目标变量的性质进行设置
// 4. 可以通过该方法赋值
Object.defineProperty(person, 'name', {
    // ? configurable
    // 1. true  可再使用Object.defineProperty修改enumerable/writable/value
    // 2. false 不再使用Object.defineProperty修改enumerable/writable
    configurable: false,
    // ? enumerable
    // 1. true forin可遍历
    // 2. false forin不可遍历
    enumerable: true,
    // ? writable 
    // 1. true  可用 (对象.属性名 = 新值)
    // 2. false 不可用 (对象.属性名 = 新值) 
    // 3. true|false 都不影响使用Object.defineProperty方式赋值
    writable: true,
    // ? value
    // 1. 若属性定义则赋值
    // 2. 若属性未定义则初始值
    value: 1
})
// 再次使用Object.defineProperty修改页面
Object.defineProperty(person, 'name', {
    // 初始值或赋值不受writable/configurable影响
    value: 22,
    // 需上面Object.defineProperty的configurable属性为true才可修改!
    // 若上方configurable为false且本次赋值与上方不一致将报错
    // 若上方configurable为false且本次赋值与上方一致不报错,不过无意义.
    enumerable: true,
    // 需上面Object.defineProperty的configurable属性为true才可修改!
    // 若上方configurable为false且本次赋值与上方不一致将报错
    // 若上方configurable为false且本次赋值与上方一致不报错,不过无意义.
    writable: true
})
// 1. 当writable为true时正常赋值
// 2. false将报错
person.name = 10;
// 1. 当enumerable为true可遍历出name
// 2. false将无法遍历到name
for (const key in person) {
    console.log(key + ":" + person[key]);
}
// 无论enumerable为 true|false 对象.属性名都可调用
// 由此可见enumerable只对遍历时有用
console.log("name:" + person.name);

 get() / set() 解释与示例

// 声明一个对象
// name:'小梦' 可省略无意义不影响结果,写了也是多余
var person = { 
    // name:'小梦'
};
// ?  Object.defineProperty
Object.defineProperty(person, 'name', {
    // 当使用 person.name 时会调用 get()
    // ? 为什么使用get()
    // 1.因get()是函数块我们可以经过一些判断后返回最终结果更灵活
    get() {
        // ? 为什么不使用this.name
        // 1. 因若使用this.name相当于又一次调用了person.name又一次调用get()陷入死循环
        // ? 为什么使用this._name
        // 1. 我们希望仍使用name但是为了避免以上的情况所以相当于新增变量_name
        return this._name || '无名'
        //return this.name || '无名' //(可尝试下错误结果) 若直接使用 this.name 将会溢出
    },
    // 当使用 person.name = xx 时会调用 set
    // 有一个形参即为赋值号右边的数值
    // ? 为什么使用set()
    // 1.使用set时如果所赋值并不是所希望该变量拥有的数值时可不赋值
    set(val) {
        this._name = '小' +  val
    }
})
// 本次打印将打印无名 
// 因 get() 中判断的是 _name 是否为空 并不是 name 是否为空
console.log(person.name);
person.name = '小方';
// 将打印 小小方 因在 set() 中我们设定规则名称前需增加 小
console.log(person.name);
person.name = '小瓜';
// 将打印 小小瓜 因在 set() 中我们设定规则名称前需增加 小
console.log(person.name);
// 在控制台中打印出对象当前所拥有的数据
// 可见为有两份 小小瓜  _name 一份 name 一份
console.log(person);

延伸 Object.getOwnPropertyDescriptors/Object.getOwnPropertyDescriptor 的理解与示例

// 延伸Object.getOwnPropertyDescriptors(对象) 会获取该对象下的所有变量的属性描述符
console.log(Object.getOwnPropertyDescriptors(person))
// 延伸Object.getOwnPropertyDescriptors(对象,变量名) 会获取该对象下的单个变量的属性描述符
console.log(Object.getOwnPropertyDescriptor(person,"name"))

 

你可能感兴趣的:(Web开发)