js对象的数据属性、访问器属性和属性枚举

js对象属性

属性的类型

js对象的分两种:**数据属性 **和 访问器属性

(一) 数据属性

顾名思义,数据属性就是用来直接保存数据的属性,一般情况下,我们都只会定义和操作数据属性

数据数据的四个特性

  1. configurable 定义属性是否可以为 delete 重新定义或修改为访问器属性,默认 true
  2. enumerable 定义属性是否可以被枚举,默认 true
  3. writable 定义属性是否可以被修改,默认 true
  4. value 属性的值
显性设置属性的参数
  1. writable 测试
  const person = {};
  Object.defineProperty(person,'name',{
    writable: false, // 不可以被修改
    value: "小明"
  });
  console.log(person.name); // 小明
  // 尝试修改 name 值失败
  person.name = "大明"
  // 还是 小明
  console.log(person.name); // 小明
  1. configurable 测试,configurable 为 false 的定义是不能修改 该属性的 4 个值
  const person = {};
  Object.defineProperty(person, 'name', {
    configurable:false,// 不能重新定义属性
    value: "小明"
  });

  try{
    // delete person.name
    Object.defineProperty(person, 'name', {
      configurable:true, // 改为 true 会报错,依旧是 false 的话就不会报错
      value: "小明"
    });
  } catch(err){
    console.log(err);
  }

  // configurable 为 false 的定义是不能修改 该属性的 4 个值
  // 修改属性的value值,不会成功,但不会报错
  person.name = "大明"
  console.log(person.name); // 小明

(二 )访问器属性

访问器属性,可以有点陌生,访问器就是来操作(获取 getter,设置 setter)数据属性的

const person = {
    firstName_: '李', // 数据属性,私有属性(只是这样定义而已(规范),外部依旧可以访问)
    lastName_: '小龙', // 数据属性,私有属性
    set name(name) {
        this.firstName_ = name.slice(0, 1)
        this.lastName_ = name.slice(1,3)
    },
    get name() {
        return this.firstName_ + this.lastName_
    }
}

console.log(person);
console.log(person.name); // 李小龙
person.name = "黄飞鸿"; // 修改了 name, 实际是修改 fistName_ 和 lastName_
console.log(person.name); // 黄飞鸿

上面 name 就是访问器,可以通过它来一次性获取和设置两个 firstName_ 和 lastName_ 的组合值

Object.defineProperties 定义多个属性值

   const book = {};
  Object.defineProperties(book, {
    // 数据属性
     year_: {
       value: 2017,
       configurable: true,
       writable:true
     },
     // 数据属性
     edition: {
       value: 1,
       configurable: true,
       writable:true
     },

     // 访问器属性, MVVM 框架的 watch 属性监听器的基础
     year: {
       //value: 2018,  // 不能同时 将属性定义数据属性和访问器属性
       get() {
         return this.year_;
       },
       set(newValue) {
         if(newValue > 2017) {
           this.year_ = newValue;
           this.edition += newValue - 2017;
         }
       }
     }
  })    
  console.log(book.year, book.edition); // 2017 1
  book.year = 2019;
  console.log(book.year, book.edition); // 2019 3

不能同时 将属性定义数据属性和访问器属性

year: {
    value: 2018,  // 不能同时 将属性定义数据属性和访问器属性
    get() {
        return this.year_;
    },
    set(newValue) {
        if(newValue > 2017) {
            this.year_ = newValue;
            this.edition += newValue - 2017;
        }
    }
}

在这里插入图片描述

(三)注意!!!使用defineProperty 或 defineProperties 定义 属性时 configurable、writable、enumerable 默认值为 false

//  Object.getOwnPropertyDescriptor 和 Object.getOwnPropertyDescriptors
const person = {};
    Object.defineProperty(person, 'name', {
      value: '小明'
    })
const descriptor = Object.getOwnPropertyDescriptor(person, 'name')
console.log(descriptor);

在这里插入图片描述

(四)属性枚举

实例准备

 const animal = {
      leg: 2,
      head: 1,
      hand: 2
    }
    
    const person = {}
    Object.defineProperties(person, {
      name: {
        value: '小明',
        enumerable: true
      },
      height: {
        value: 180,
        enumerable: true
      },
      weight: {
        value: 70,
        enumerable: true
      },
      sex: {
        value: '男',
        enumerable: true
      },
      age: {
        value: 22,
        enumerable: false // 不可被枚举
      }
    })

    Object.setPrototypeOf(person, animal)
    console.log(person);

在这里插入图片描述

  1. for…in 语句

    for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

    for(let prop in person){
        console.log(prop+':'+person[prop]);
    }
    

    输出结果:属性age没有输出,因为它的enumertable特性是 false, 原型属性leg, head, hand也输出了

在这里插入图片描述

  1. Object.keys()

    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

    const keys = Object.keys(person);
    console.log(keys);
    

    输出结果:只有对象自身的可枚举属性,不可枚举属性age没输出,原型属性也没输出

在这里插入图片描述

  1. Object.getOwnPropertyNames(obj)

    Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

    const propNames = Object.getOwnPropertyNames(person);
    console.log(propNames);
    

    输出结果:对象自身所有属性都输出了

在这里插入图片描述

  1. Object.getOwnpropertySymbols()

    Object.getOwnPropertySymbols(obj) 返回一个数组,包含对象自身的所有 Symbol 属性的键名。

    // 添加 symbol 属性
    const idSymbol = Symbol("id");
    Object.defineProperty(person, idSymbol, {
        value: 1
    })
    console.log(person);
    
    const propSymbols = Object.getOwnPropertySymbols(person);
    console.log(propSymbols);
    

    输出结果:只返回对象自身的 symbol(id) 属性名

在这里插入图片描述

  1. Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

  const ownKeys = Reflect.ownKeys(person);
  console.log(ownKeys);

输出结果:不可枚举属性 age 和 symbol 属性 symbol(id)都输出了

在这里插入图片描述

属性枚举特性汇总,打钩表示会被输出

方法可枚举属性不可枚举属性继承属性symbol属性
for…in…
Object.keys
Object.getPropotyNames
Object.getPropotySymbols
Reflect.ownKeys
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值