90% JS开发者不知道的属性陷阱:你的writable为什么失效了?

近日发现:为什么即使设置 writable:false ,你的属性依然被修改?是引擎出轨了还是代码缩水了?让我今天来聊一聊 get 和 set 的小细节。

在 JavaScript 中,访问描述符(Accessor Descriptor)数据描述符(Data Descriptor) 是两种不同的属性描述符类型,又要找不同了吗:

1. 数据描述符(value + writable

  • 适用于普通属性,如:

    js 复制代码
    const obj = {};
    Object.defineProperty(obj, 'name', {
      value: 'Alice',
      writable: false, // 控制是否可修改
    });
    obj.name = 'Bob'; // 静默失败(严格模式会报错)
    console.log(obj.name); // 'Alice'(未被修改)
    • 如果 writable: false,则 value 不可被重新赋值 (无论是直接赋值还是 Object.defineProperty 修改)。

2. 访问描述符(get + set

  • 适用于 计算属性 (通过 getter/setter 动态控制):

    js 复制代码
    const obj = {};
    Object.defineProperty(obj, 'name', {
      get() { return this._name; },
      set(val) { this._name = val; },
      // 注意:这里没有 `value` 或 `writable`!
    });
    obj.name = 'Bob'; // 调用 setter
    console.log(obj.name); // 'Bob'(通过 getter 获取)
    • 访问描述符会忽略 valuewritable ,只关心 getset

    • 即使你强行加上 writable: false只要提供了 set,属性依然可写

      js 复制代码
      Object.defineProperty(obj, 'name', {
        get() { return this._name; },
        set(val) { this._name = val; },
        writable: false, // 被忽略!
      });
      obj.name = 'Bob'; // 仍然可以调用 setter

加false都能写,我直接狠狠地 了。

3. 冲突规则

  • 如果同时提供 value/writableget/set ,JS 会报错:

    js 复制代码
    // 错误示例!
    Object.defineProperty(obj, 'name', {
      value: 'Alice',
      get() { return 'Bob'; }, // TypeError: Invalid property descriptor
    });

总结

描述符类型 关键属性 writable: false 的影响
数据描述符 value, writable 阻止直接修改 value
访问描述符 get, set writable 被忽略 ,由 set 控制

其实文章看总结感觉就够了,加深理解再去看例子。

结论

  • 对于 访问描述符writable 无意义,是否可写完全由 set 是否存在决定。

  • 如果你希望一个访问器属性 只读 ,直接 不提供 set 即可:

    js 复制代码
    Object.defineProperty(obj, 'readOnlyProp', {
      get() { return 'Cannot change me!'; },
      // 无 setter
    });
    obj.readOnlyProp = 'New'; // 静默失败(严格模式报错)

谢谢观看

相关推荐
Laravel技术社区15 分钟前
用PHP8实现斗地主游戏,实现三带一,三带二,四带二,顺子,王炸功能(第二集)
前端·游戏·php
m0_738120721 小时前
应急响应——知攻善防Web-3靶机详细教程
服务器·前端·网络·安全·web安全·php
لا معنى له4 小时前
目标检测的内涵、发展和经典模型--学习笔记
人工智能·笔记·深度学习·学习·目标检测·机器学习
hh随便起个名7 小时前
力扣二叉树的三种遍历
javascript·数据结构·算法·leetcode
我是小路路呀8 小时前
element级联选择器:已选中一个二级节点,随后又点击了一个一级节点(仅浏览,未确认选择),此时下拉框失去焦点并关闭
javascript·vue.js·elementui
程序员爱钓鱼8 小时前
Node.js 编程实战:文件读写操作
前端·后端·node.js
PineappleCoder8 小时前
工程化必备!SVG 雪碧图的最佳实践:ID 引用 + 缓存友好,无需手动算坐标
前端·性能优化
JIngJaneIL9 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
敲敲了个代码9 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
澄江静如练_9 小时前
列表渲染(v-for)
前端·javascript·vue.js