前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库configurable false 禁止哪些操作
JavaScript对象与原型

属性设成 configurable:false 之后,哪些操作就做不了了?

configurable: false 锁的是属性的「定义」,不是属性的「值」。锁住后不能删除,不能改 enumerable,不能在数据属性和访问器之间切换;但 writable 为 true 时值照样能改,writable 也还能从 true 单向改成 false。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#对象与原型#流处理
先看核心答案读代码示例
理解线索

`configurable` 管的是描述符能不能再动

  1. 删除delete obj.key 失败,属性永远留在对象上
  2. 重新定义enumerable、configurable 不能改,数据属性和访问器不能互换
  3. writable 单向降级唯一放行的修改是 writable 从 true 变 false

很多人以为 configurable: false 等于只读。它不管值,obj.key = 2 能不能成功只看 writable。

核心回答

先记住这个答案

configurable: false 之后,属性不能被删除,描述符也基本锁死:enumerable 不能改,configurable 不能再改回 true,数据属性不能换成 get / set 访问器,反过来也不行。只有两件事还能做:writable 为 true 时照常改值,以及把 writable 从 true 改成 false。所以它管的是「这个属性长什么样」,不是「这个属性的值是多少」。

  • 不可配置属性不能删除
  • 不可配置后不能改枚举性或属性类型
  • writable 可单向关闭
  • 不影响改值,锁值要靠 writable: false

逐条试一遍

面试里光背规则容易漏,直接拿一个 configurable: false、writable: true 的属性挨个试最清楚。

哪些操作报错,哪些能过JavaScript
const obj = {}
Object.defineProperty(obj, 'id', { value: 1, writable: true, enumerable: true, configurable: false })

console.log(Reflect.deleteProperty(obj, 'id')) // false,删不掉
obj.id = 2
console.log(obj.id) // 2,writable 还是 true,照样能改值

const tryDefine = (desc) => {
  try {
    Object.defineProperty(obj, 'id', desc)
    console.log('ok')
  } catch (e) {
    console.log(e.name)
  }
}
tryDefine({ enumerable: false }) // 改 enumerable
tryDefine({ get() { return 3 } }) // 数据属性换成访问器
tryDefine({ writable: false }) // true 改成 false,唯一放行的方向
tryDefine({ writable: true }) // 再改回 true
查看输出与解释
false
2
TypeError
TypeError
ok
TypeError

这里用 Reflect.deleteProperty 是为了拿到布尔返回值。换成 delete obj.id,非严格模式下同样返回 false,严格模式下直接抛 TypeError。 Object.defineProperty 不管在不在严格模式,改不了都会抛 TypeError。这点和普通赋值不一样,普通赋值给只读属性在非严格模式下是静默失败。 最后两行说明 writable 是单向的:可以从 true 降到 false,降完之后这个属性就彻底成了常量,值和描述符都动不了了。

为什么允许 writable 往下改

规范的思路是:configurable: false 承诺的是「属性不会变得更宽松」。把 writable 从 true 改成 false 是在收紧权限,不会破坏任何人对这个属性的假设,所以放行。反过来从 false 改成 true,本来的常量突然能改了,就违反了承诺。

还有个细节:值没变的「重新定义」不会报错。比如上面的 id 已经是常量,值是 2,再调用 Object.defineProperty(obj, 'id', { value: 2 }) 不会报错。新值和旧值用 Object.is 比较相同,就当作没改;传 3 才会抛 TypeError。

和 Object.seal、Object.freeze 的关系
Object.seal(obj) 做两件事:禁止新增属性,把所有自有属性都设成 configurable: false。所以被 seal 的对象,属性能改值、不能删除、不能重新定义。Object.freeze(obj) 在 seal 基础上,再把所有数据属性的 writable 设成 false,就成了只读。理解了 configurable 和 writable 这两个开关,seal 和 freeze 的区别就不用死记。
回答前,多想一步

容易答错的地方

把 configurable: false 当成只读
它不锁值。值能不能改只看 writable,访问器属性则看有没有 set。想让属性只读,要设 writable: false。
以为 defineProperty 默认就是可配置的
用 Object.defineProperty 新增属性时,没写的 writable、enumerable、configurable 全部默认 false。所以随手写一句 Object.defineProperty(obj, 'x', { value: 1 }),这个属性就已经删不掉了。而普通赋值 obj.x = 1 创建的属性,三个开关都是 true。
以为访问器属性锁住后还能换 getter
访问器属性 configurable: false 后,get 和 set 函数都不能换成别的函数,只有传入和原来同一个函数引用才不报错。
试着用自己的话回答

面试官还会怎么问?

内置对象上有哪些 configurable: false 的属性?

比如 Math.PI,它是 writable: false、configurable: false,所以 Math.PI = 3 无效,delete Math.PI 返回 false。还有用 var 在全局声明的变量,挂在全局对象上的那个属性也是 configurable: false,所以 delete 删不掉。

Vue 2 的响应式为什么对某些属性不生效?

Vue 2 用 Object.defineProperty 把属性改成 getter 和 setter。源码里会先检查属性描述符,遇到 configurable: false 的属性就直接跳过,因为没法重新定义它。被 Object.freeze 过的数据也是这个原因不会变成响应式。

怎么查看一个属性当前的描述符?

用 Object.getOwnPropertyDescriptor(obj, 'id') 查单个,Object.getOwnPropertyDescriptors(obj) 查全部。返回的对象里能直接看到 value、writable、enumerable、configurable 四个字段,访问器属性则是 get、set、enumerable、configurable。

从一道题,走向一组知识

把知识连起来

对象与原型

可选链 ?. 和用 && 一层层判断,有什么不一样?

都在讲属性访问的边界,一个管属性还能不能被改动,一个管属性不存在时怎么安全读取。

对象与原型

对象里的数字键,遍历出来为什么总排在最前面?

defineProperty 新增的属性同样参与键的排序,整数键为什么排前面在那篇讲。

参考资料

  • JavaScript:对象与原型参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 逐条试一遍
  3. 为什么允许 writable 往下改
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑