【JavaScript高级】对象相关:对象属性、属性描述符(数据属性,存取属性)

对象属性的操作

定义

我们可以使用属性描述符 对一个属性进行比较精准的操作控制

  • 通过属性描述符可以精准的添加或修改对象的属性
  • 需要使用 Object.defineProperty

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

Object.defineProperty(obj, prop, descriptor)

三个参数:

  • obj要定义属性的对象
  • prop要定义或修改的属性的名称或 Symbol
  • descriptor要定义或修改的属性描述符

属性描述符

可以看JS 属性描述符
浅谈 JS 对象属性描述符(property descriptor)对象

顾名思义是用来描述属性的。假如有一个对象:

var obj = {
   name: "why",
    age: 18,
    height: 1.88
}

对象里有属性name,我们对它有这样的描述:

对name属性:{
描述1:不能被删除
描述2:不能写入,只能读取
描述3:在获取值时只能获取到why
描述4:在遍历时不要出现
}

这就是属性描述符。

属性描述符分类

  • 数据属性 描述符
  • 存取属性 描述符

在这里插入图片描述

数据属性描述符

Configurable:表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性描述符.

  • 直接在一个对象上定义某个属性,默认true
  • 通过属性描述符定义一个属性,默认false
// 直接在一个对象上定义某个属性, 这个属性的Configurable默认为true
var obj = {
  name: "why",
  age: 18,
};

//把name属性的configurable改为false
Object.defineProperty(obj, "name", {
  configurable: false,
});

//则name属性不能通过delete删除
delete obj.name;
console.log(obj); // {name: 'why', age: 18}

// 通过属性描述符定义一个属性, 这个属性的Configurable默认为false
Object.defineProperty(obj, "address", {});
delete obj.address;
console.log(obj); // {name: 'why', age: 18, address: undefined}

Enumerable:表示属性是否可以通过for-in或者Object.keys()返回该属性

  • 直接在一个对象上定义某个属性,默认true
  • 通过属性描述符定义一个属性,默认false
// 直接在一个对象上定义某个属性, 这个属性的Configurable默认为true
var obj = {
  name: "why",
  age: 18,
};

// 告诉JS引擎,obj的name属性不可枚举
Object.defineProperty(obj, "name", {
  enumerable: false,
});

// 通过属性描述符定义一个属性, 这个属性的Enumerable默认为false
Object.defineProperty(obj, "address", {});
// 枚举obj
console.log(Object.keys(obj)); // ['age']

Writable:表示是否可以修改属性的值

  • 直接在一个对象上定义某个属性,默认true
  • 通过属性描述符定义一个属性,默认false
// 直接在一个对象上定义某个属性, 这个属性的Writable默认为true
var obj = {
  name: "why",
  age: 18,
};

// 告诉JS引擎obj的name属性是不可修改的, 不可写入(只读)
Object.defineProperty(obj, "name", {
  writable: false,
});

// 通过属性描述符定义一个属性, 这个属性的Writable默认为false
Object.defineProperty(obj, "address", {});

obj.name = "kaisa";
console.log(obj.name); // why 因为name不可改
obj.address = "成都市";
console.log(obj.address); // undefined //默认不可改

value:属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改,默认是undefined

var obj = {
  name: "why",
  age: 18,
};

// 告诉JS引擎, 读取obj的name属性会返回kaisa这个值
Object.defineProperty(obj, "name", {
  value: "kaisa",
});

console.log(obj.name); // kaisa

存取属性描述符

ConfigurableEnumerable与数据数据描述符的相同。

set:设置属性时就会执行的函数。默认为undefined。当获取属性时, 就会执行set函数。

var obj = {
  name: "why",
  age: 18,
};

// 当设置name属性的时候, 就会调用set函数
Object.defineProperty(obj, "name", {
  set: function (value) {
    console.log("set方法被调用了", value);
  },
});

obj.name = "kaisa"; // set方法被调用了 kaisa
obj.name = "vn"; // set方法被调用了 vn

get:获取属性时就会执行的函数。默认为undefined。当获取属性时, 就会执行get函数。

var obj = {
  name: "why",
  age: 18,
};

var _name = "";
// 当设置name属性的时候, 就会调用set函数
Object.defineProperty(obj, "name", {
  set: function (value) {
    console.log("set函数被调用了", value);
    _name = value;
  },
  get: function () {
    console.log("get函数被调用了");
    return _name;
  },
});

obj.name = "kaisa"; // set方法被调用了 kaisa
console.log(obj.name); // get函数被调用了 kaisa
obj.name = "vn"; // set方法被调用了 vn
console.log(obj.name); // get函数被调用了 vn

同时定义多个属性

Object.defineProperties() 方法直接在一个对象上定义多个新的属性描述符或修改现有属性,并且返回该对象:

var obj = {
  name: "why",
  age: 18,
  height: 1.88,
};

Object.defineProperties(obj, {
  name: {
    configurable: true,
  },
  age: {
    configurable: false,
    writable: false,
  },
  height: {
    set: function (value) {
      console.log("set函数被调用", value);
    },
  },
});

其他对象方法(了解)

获取对象的属性描述符:getOwnPropertyDescriptor

获取对象所有属性的描述符:getOwnPropertyDescriptors

禁止对象扩展新属性:preventExtensions——给一个对象添加新的属性会失败(在严格模式下会报错)

密封对象,不允许配置和删除属性:seal

  • 实际是调用preventExtensions
  • 将现有属性的configurable:false

冻结对象,不允许修改现有属性:freeze

  • 实际上是调用seal
  • 将现有属性的writable: false

参考

coderwhy的课
JavaScript对象的增强、属性描述符介绍
JS 属性描述符
浅谈 JS 对象属性描述符(property descriptor)对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值