函数声明创建独立作用域并影响变量可见性与生命周期,其会被提升至作用域顶部,而变量赋值不提升;全局变量可读但修改需谨慎,局部变量封闭安全;es6块级作用域依附于函数作用域。

函数声明本身不直接创建变量,但它深刻影响变量的可见范围和生命周期。理解这一点,关键在于区分“函数怎么写”和“函数里能用什么变量”。
函数声明决定作用域边界
函数声明(function fn() { })会创建一个独立的作用域。在这个大括号内部定义的变量,除非显式暴露,否则外部完全不可见。
- 函数内用 var、let 或 const 声明的变量,只在该函数体内有效
- 即使同名,函数内的变量也会屏蔽外部同名变量(包括全局变量)
- 函数可以访问其外部作用域的变量(闭包基础),但外部无法反向访问函数内部变量
函数声明位置影响变量可调用时机
JavaScript 中,函数声明会被提升(hoisting)到当前作用域顶部,而变量声明(仅声明,不含赋值)也会提升,但赋值不会。
- function say() { return 'hi'; } 可以在定义前调用
- var say = function() { return 'hi'; }; 必须先定义再调用,否则报 TypeError: say is not a function
- 若函数内有同名变量声明,如 var say = 'text';,则函数声明虽被提升,但变量声明也会覆盖,导致调用时报错或返回 undefined
全局与局部变量在函数中的行为差异
函数是变量作用域切换的关键节点。全局变量天然可读,但修改需谨慎;局部变量封闭安全,但生命周期短暂。
- 不加 var/let/const 直接赋值的变量(如 count = 10)会自动挂到全局对象(如 window.count),无论是否在函数内
- 用 global(Python)或 global/$GLOBALS(PHP)才能在函数内修改真正的全局变量
- JS 中没有 global 关键字,需显式引用 window.xxx(浏览器)或 globalThis.xxx 来读写全局变量
块级作用域与函数作用域的配合
ES6 引入 let/const 后,JS 支持真正的块级作用域(如 if、for 内部),但它仍依附于外层函数作用域。函数仍是作用域组织的核心单位。
- 一个 for (let i = 0; ...) 中的 i 在每次迭代中都是新绑定,不会泄漏到函数体外
- 但若用 var i,i 会提升到函数顶部,整个函数内都可见
- 函数表达式或 IIFE(立即执行函数)常被用来人为制造隔离作用域,模拟块级封装效果











