非严格模式下函数声明是函数作用域吗?为何示例中提前调用inside()报错
问题解答
你对非严格模式(sloppy mode)下函数声明作用域的认知存在部分偏差,块内函数声明的提升逻辑和普通var声明并不完全一致,具体原因如下:
- ES5及更早的ECMAScript规范中,没有定义在代码块(
if/for等)内编写函数声明的行为,各浏览器早期实现存在差异,ES6才将该场景纳入规范,并为非严格模式保留了兼容规则。 - 非严格模式下,块内函数声明会按照两步规则处理:
- 首先在外层函数作用域的顶部,声明一个和函数名同名的变量,这一步和
var的提升行为一致,变量初始值为undefined - 只有当代码执行进入块内、走到函数声明所在的行时,才会把函数本身赋值给外层作用域的这个同名变量
- 首先在外层函数作用域的顶部,声明一个和函数名同名的变量,这一步和
- 你提供的代码中,在
if块外调用inside()时,块内的函数声明代码还未执行,此时inside的取值还是undefined,调用自然会抛出TypeError: inside is not a function的错误。
你可以通过以下代码验证这个逻辑:
function outside() { var first = 'hello'; console.log(inside) // 输出 undefined,证明变量已经提升但未被赋值为函数 // inside(); 此处调用会报错 if (true) { var second = 'second'; function inside() { var third = 'third'; console.log(third); } inside(); } console.log(inside) // 执行完块内逻辑后,此处输出函数本身 } outside();
额外提示
- 上述特殊规则仅在非严格模式下生效,严格模式中块内函数声明的作用域仅局限于块内部,外层作用域完全无法访问,逻辑更符合直觉。
- 生产环境建议避免在代码块内编写函数声明,避免出现不符合预期的作用域问题,如有需要可以用函数表达式代替。
内容的提问来源于stack exchange,提问作者Talha Ali
相关产品推荐
相关产品推荐

