JavaScript函数内全局变量为何报错?调用前后访问机制疑问
为什么未声明的变量i会变成全局变量?
这其实是JavaScript里隐式全局变量的特性在起作用,我来一步步给你理清楚:
1. 隐式全局变量的创建逻辑
你在numPrinter函数里写的是i = 30;,这里没有用var、let或者const来声明变量i。JavaScript遇到这种未声明就赋值的变量时,会做两件事:
- 沿着当前作用域链向上查找,看有没有已经声明的
i变量 - 如果一直找到全局作用域都没找到
i,就会自动在全局作用域中创建一个名为i的全局变量,然后给它赋值30
这就意味着,i从一开始就不是函数内部的局部变量,而是属于全局作用域的——只是它的创建时机是在numPrinter()被执行的时候。
2. 调用前后的差异原因
- 调用
numPrinter()之前:全局作用域里还没有i这个变量,所以执行console.log(i)时,JavaScript找不到这个变量,自然抛出ReferenceError - 调用
numPrinter()之后:函数执行了i = 30;,这时候全局作用域被创建了i变量并完成赋值,所以再执行console.log(i)就能输出30了
3. 对比验证:如果是局部变量会怎样?
如果把函数里的代码改成var i = 30;(用var声明),那i就是函数内部的局部变量,全局作用域不会有这个变量。这时候哪怕调用了numPrinter(),之后执行console.log(i)还是会抛出ReferenceError——这也能反过来证明之前的i是被隐式创建的全局变量。
注意事项
这种隐式创建全局变量的行为很容易造成全局作用域污染,引发难以排查的bug。所以在写JavaScript代码时,一定要用var、let或const声明所有变量,避免这种意外情况。
内容的提问来源于stack exchange,提问作者Noder
相关产品推荐
相关产品推荐

