You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何隐式变量可配置,显式变量与函数声明却不可?

为什么隐式全局变量的configurable为true,而var声明的全局变量(及函数声明)为false?

这问题问到点子上了!核心原因其实是全局成员的创建机制完全不同,咱们一步步拆解:

1. 隐式全局变量:本质是给全局对象“手动加属性”

当你直接写foo = ''时,在浏览器环境下等价于window.foo = ''——这就是个普通的对象属性赋值操作。根据ES规范,通过这种方式添加的对象属性,默认的属性描述符就是:

  • configurable: true
  • enumerable: true
  • writable: true
    所以你用Object.getOwnPropertyDescriptor拿到的结果自然是configurable: true,这类属性可以被随意删除、修改描述符。

2. var声明的全局变量:引擎的“特殊绑定流程”

用var bar = ''声明全局变量时,这属于JS引擎的变量声明绑定流程。虽然最终也会成为window的属性,但这个过程是规范专门定义的:引擎会强制把该属性的configurable设为false,同时保留enumerable和writable为true。

这么设计的目的很实际:避免var声明的全局变量被意外删除(毕竟configurable: false的属性无法用delete操作符移除),保证变量声明的稳定性。

3. 函数声明的情况和var一致

你问题里提到的函数声明,其实和var是一个逻辑:全局作用域下的函数声明也是通过绑定机制创建的,所以它的configurable同样是false(另外函数声明的enumerable默认是false,这是和var的小区别)。

直观验证一下差异

咱们用delete操作符试试,就能立刻看到区别:

// 隐式变量:可以被删除
foo = '';
delete window.foo; // 返回 true
console.log(window.foo); // undefined

// var声明的变量:无法被删除
var bar = '';
delete window.bar; // 返回 false
console.log(window.bar); // ''

// 函数声明:同样无法被删除
function baz() {}
delete window.baz; // 返回 false
console.log(window.baz); // ƒ baz() {}

总结一下

一句话说清:

隐式全局变量是普通对象属性赋值,遵循默认的属性描述符规则;而var声明和函数声明是JS引擎通过变量绑定机制创建的全局成员,规范强制将其configurable设为false,以此保障声明的成员不会被轻易移除。

内容的提问来源于stack exchange,提问作者Ben Aston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:27:54