掌握JavaScript对象属性修饰符:精确控制你的代码

JavaScript对象属性修饰符:控制属性的行为和可访问性

JavaScript是一门强大而灵活的编程语言,它提供了多种方法来定义和操作对象的属性。其中一个重要的概念是属性修饰符,它们允许我们控制属性的行为和可访问性。

基本属性修饰符

JavaScript中的属性修饰符主要包括writableenumerableconfigurable。我们可以使用Object.defineProperty方法来设置这些属性。

writable(可写性)

writable属性决定了属性是否可以被重新赋值。当设置为false时,属性不可被重新赋值,否则可以。

ini 复制代码
var obj = {
  b: 2,
};

Object.defineProperty(obj, 'a', {
  value: 10,
  writable: false, // 不可重写
});

obj.a = 'abc'; // 这里会抛出错误,因为属性a不可重写
console.log(obj.a); // 输出仍然是10

enumerable(可枚举性)

enumerable属性决定了属性是否会出现在for...in循环中或通过Object.keys方法获取。当设置为false时,属性不可被遍历,否则可以。

javascript 复制代码
var obj = {
  b: 2,
};

Object.defineProperty(obj, 'a', {
  value: 10,
  enumerable: false, // 不可遍历
});

for (var key in obj) {
  console.log(key); // 这里不会输出属性a
}

var keys = Object.keys(obj);
console.log(keys); // 这里不会包含属性a

configurable(可配置性)

configurable属性决定了属性是否可以被删除或属性描述符是否可以被修改。当设置为false时,属性不可被删除或修改属性描述符,否则可以。

javascript 复制代码
var obj = {
  b: 2,
};

Object.defineProperty(obj, 'a', {
  value: 10,
  configurable: false, // 不可修改描述符本身
});

// 下面的代码会抛出错误,因为属性a不可被删除
delete obj.a;

Object.defineProperty(obj, 'a', {
  writable: true, // 这里会抛出错误,因为属性a不可被修改
});

obj.a = 'abc'; // 这里会抛出错误,因为属性a不可重写

使用getter和setter

除了基本的属性修饰符,JavaScript还允许我们使用getter和setter来定义属性的访问和赋值行为。这对于在访问或修改属性时执行特定操作非常有用。

javascript 复制代码
var obj = {};

Object.defineProperty(obj, 'a', {
  get: function () {
    return 123; // 获取属性a时总是返回123
  }, 
  set: function (val) {
    throw new Error(
      `属性a不能被重新赋值,你尝试赋值为${val}`
    );
  },
});

console.log(obj.a); // 输出123

obj.a = 'abx'; // 这里会抛出错误,因为属性a不可重写

在上面的示例中,我们使用getter来获取属性a的值,并使用setter来阻止对属性a的重新赋值。这允许我们在属性访问和赋值时执行自定义逻辑。

在class类中的使用

在ES6类(Class)的构造函数中定义属性的getter和setter方法,可以直接在构造函数中使用Object.defineProperty

javascript 复制代码
class MyClass {
  constructor() {
    this._a = 123;

    Object.defineProperty(this, 'a', {
      get: function () {
        return this._a;
      },
      set: function (val) {
        throw new Error(`属性a不能被重新赋值,你尝试赋值为${val}`);
      },
    });
  }
}

const instance = new MyClass();
console.log(instance.a); // 输出123
instance.a = 456; // 这里会抛出错误,因为属性a不可重写

当使用ES6类(Class)来定义对象时,可以更简洁地定义属性的getter和setter方法,而不需要使用Object.defineProperty。ES6引入了一种更友好的语法,可以在类中使用getset关键字来创建属性的getter和setter。

javascript 复制代码
class MyClass {
  constructor() {
    this._a = 123;
  }

  get a() {
    return this._a; // 这是属性a的getter方法
  }

  set a(val) {
    throw new Error(
      `属性a不能被重新赋值,你尝试赋值为${val}`
    );
  }
}

结合遇到的面试题

  • js怎么观察对象是否被调用呢?
  • 获取对象属性在什么情况下会报错?
  • 手写一个ObjectFreeze
相关推荐
ydyd202604217 分钟前
设备OEE怎么提升?数据采集+分析优化的完整方案
java·服务器·前端
(╹◡╹)28 分钟前
11.RK3588本地大模型内存评估优化
java·linux·前端
不正经学生33 分钟前
C语言字符串函数进阶:安全版函数 + 错误处理 + 子串查找
c语言·开发语言·c++·算法·面试
Dr.kangder34 分钟前
嵌入式面试总结(十四)——中断处理
单片机·面试·职场和发展·架构·硬件架构·嵌入式
电气研究所1 小时前
Java + Redis 实现工业设备告警去抖,避免变频器故障重复推送
java·前端
AI视觉网奇1 小时前
cannot import name ‘model_urls‘ from ‘torchvision.models.resnet‘
linux·前端·javascript
Vuji1 小时前
深入 pi-agent 内核:完整追踪一次 CLI 交互的完整链路
前端·agent
Dr.kangder1 小时前
嵌入式面试总结(十)——流水线
单片机·嵌入式硬件·面试·职场和发展·系统架构·嵌入式
zfoo-framework1 小时前
安装pi agent 支持duojie和deepseek
java·服务器·前端
Sca_杰1 小时前
微信客服API对接速通
javascript·node.js