var与let声明Permissions在IIFE中的类型差异原因探究
问题解析:var vs let声明Permissions后的typeof差异
核心原因
这是全局作用域下var与let的绑定规则差异,加上浏览器原生Permissions API的存在共同导致的。
分步拆解
var声明的全局变量会绑定到window对象
在浏览器环境中,用var声明的全局变量会直接成为window对象的属性。而浏览器原生提供了Permissions API,其中window.Permissions是一个构造函数(typeof结果为function)。
当你写var Permissions;时,只是声明了变量但未赋值,此时这个变量会直接指向window.Permissions(原生构造函数),而非undefined。自执行函数对var变量的影响
自执行函数的参数是局部变量,但传入的表达式Permissions || (Permissions = {})中的Permissions是全局变量:
- 因为全局
Permissions此时是原生的function(真值),所以||运算直接返回这个function,不会执行Permissions = {}。 - 函数内部只是给这个function对象添加了
ADMIN、READ_ONLY等属性(JS中函数也是对象,可以扩展属性),但全局的Permissions变量始终指向原生构造函数,因此最后typeof Permissions输出function。
- let声明的变量独立于window
用let声明的全局变量不会成为window的属性,是独立的块级作用域变量。let Permissions;声明后变量值为undefined(假值):
- 自执行函数的表达式
Permissions || (Permissions = {})会执行Permissions = {},将全局的Permissions变量赋值为一个新对象。 - 函数内部对这个对象添加属性,最终全局
Permissions是普通对象,typeof结果为object。
验证小技巧
如果在无原生Permissions API的环境(比如Node.js)中运行这段代码,两种声明方式的typeof结果都会是object,这也能验证是浏览器原生API导致的差异。
内容的提问来源于stack exchange,提问作者Edi
相关产品推荐
相关产品推荐

