JS对象的属性描述符

创建对象的方式

方式一:通过new Object方式创建

js 复制代码
    var obj = new Object()
    obj.name = 'ywq'
    obj.age = 12
    obj.friends = { name: 'yyy', age: 11 }
    obj.action = function() {}

方式二:通过字面量形式创建

js 复制代码
    var obj = {
        name: 'ywq',
        age: 12,
        friends: { name: 'yyy', age: 11 },
        action: function() {}
    }

两种方式都可以创建对象,但是new Object()不建议使用 ,通过代码可以看出代码不够直观阅读性差,属性需要一个一个进行添加

属性描述符-对象的一些用法

js 复制代码
    var obj = { name: '水杯', color: '蓝色', capacity: '800ml' }
  • 获取对象属性的值
js 复制代码
    console.log(obj.name) // 水杯
  • 设置对象某个属性的值/给对象添加新属性
js 复制代码
    obj.color = '粉色'
    obj.shape = 'cylinder'
  • 删除对象的某个属性
js 复制代码
    delete obj.capacity
    console.log(obj) // {name: '水杯', color: '蓝色'}

我们可以对对象的属性进行增/删/改/查,那我们能不能精准的对对象进行操作?(比如:不能对对象的某个属性进行其他操作)

属性描述符 Object.defineProperty() 和 Object.defineProperties()

  • 数据属性描述符 (configurable, enumerable, writable, value)
  • 存取属性描述符 (configurable, enumerable, get, set)

对象的属性描述符分为数据属性描述符和存取属性描述符,两种属性描述符不可共存,只能选择其中一种

写法:

  • Object.defineProperty(要操作的对象, 要操作对象的某个属性, { 数据属性描述符 })
  • Object.defineProperties(要操作的对象, {})
数据属性描述符
  • 属性是否可以删除/重新配置 configurable
js 复制代码
    var obj = { name: "华为手机", color: "白色" }
    Object.defineProperty(obj, 'color', {
        configurable: false,
    });
    delete obj.color;
    console.log(obj);
    console.log(obj) // {name: '华为手机', color: '白色'}

configurable 为false时,无法对配置的对应属性重新修改属性描述符

js 复制代码
    var obj = { name: "华为手机", color: "白色" }
    Object.defineProperty(obj, 'color', {
        configurable: false,
    });
    Object.defineProperty(obj, 'color', {
        configurable: true
    });
    obj.color = '红色'
    console.log(obj) // test.js:5 Uncaught TypeError: Cannot redefine property: color at Function.defineProperty 
  • 属性是否可被枚举 enumerable enumerable为false时,不能被枚举
js 复制代码
    var obj = { name: '华为手机', color: '白色' }
    Object.defineProperty(obj, 'color', {
        configurable: true,
        enumerable: false
    })
    // 1.
    console.log(obj) // { name: '华为手机' }  在控制台中打印
    console.log(obj.color) // 白色

    // 2.
    for(var key in obj) {
        console.log(key) // name
    }
  • 给属性重新赋值 writable writable为false时,不能给属性重新赋值
js 复制代码
    var obj = { name: '华为手机', color: '白色' }
    Object.defineProperty(obj, 'name', {
        configurable: true,
        enumerable: true,
        writable: false
    })
    obj.name = '小米'
    console.log(obj) // { name: '华为手机', color: '白色' }
  • 设置属性的值
js 复制代码
    var obj1 = { name: '华为手机' }
    Object.defineProperty(obj1, 'name', {
        value: 'OPPO手机'
    })
    console.log(obj1) // {name: 'OPPO手机'}
  • 添加新的属性
js 复制代码
    var obj1 = { name: '华为手机' }
    Object.defineProperty(obj1, 'model', {
        value: 'Meta 5'
    })
    console.log(obj1) // {name: '华为手机', model: 'Meta 5'}

`

Object.defineProperty(obj, 'height', {属性描述符}) 属性描述符没有配置时,对象属性的默认配置如下:

  • configurable 默认值:false
  • enumerable 默认值: false
  • writable 默认值:false
  • value 默认值:undefined

字面量对象的属性也有属性描述符,默认都为true,可以通过Object.getOwnProperty(对象, 属性)获取

var obj = { size: '40*40', grade: 'A' } `

  • 对对象多个属性同时添加属性描述符
js 复制代码
    var obj = {}
    Object.defineProperties(obj, {
        name: {
            configurable: true,
            enumerable: true,
            writable: true,
            value: '华为手机'
        },
        color: {
            configurable: true,
            enumerable: true,
            writable: false,
            value: '粉色'
        }
    })
    obj.color = '黑色'
    console.log(obj) // {name: '华为手机', color: '粉色'}

获取对象的所有属性描述符,通过Object.getOwnProperties(obj)

存取属性描述符

存取属性描述符和数据属性描述符相同不同,不再说明

` 对象的存取属性描述符使用场景

  • 和私有属性一同使用
  • 对对象的属性进行截获(vue2响应式原理) `
js 复制代码
    var obj = { name: "ywq", _age: 12 };
    Object.defineProperty(obj, "age", {
        configurable: true,
        enumerable: true,
        get: function () {
            log(obj);
            return this._age;
        },
        set: function (value) {
            change();
            this._age = value;
        },
    });

    function change() {
    console.log("set操作时执行了:", { address: "河南" });
    }
    function log(s) {
    console.log("get操作时执行了:", s);
    }

    obj.age = 18;
    console.log(obj.age);

对象的其他用法

  • Object.preventExtensions(对象名称) 禁止对对象进行扩展,禁止添加新属性
js 复制代码
    var obj = { name: 'ywq', age: 12 }
    Object.preventExtensions(obj)
    obj.age = 23
    obj.sex = '未知'
    obj.height = '未知'
    console.log(obj) // {name: 'ywq', age: 23}
  • Object.seal(对象名称,对象属性) 禁止删除对象的某个属性
js 复制代码
    var obj = { name: 'ywq', age: 12 }
    Object.seal(obj, 'name')
    console.log(obj) // name: 'ywq', age: 12}
  • Object.freeze(对象名称) 冻结某个对象
js 复制代码
    var obj = { name: 'ywq', age: 12 } 
    Object.freeze(obj)
    obj.age = 18
    obj.height = '未知'
    console.log(obj) // {name: 'ywq', age: 12}
相关推荐
小阮的学习笔记7 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜8 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=8 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
小政爱学习!33 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。38 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼44 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
web行路人1 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0011 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9212 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp