文章 评论 浏览 33
老师您好,我想问一下function test() { console.log("out"); } (function () { if (false) { function test() { console.log("in"); } } test(); })(); // 为什么这里输出的结果不是out,而是直接报错呢?
老师您好,我想问一下
function test() { console.log("out"); } (function () { if (false) { function test() { console.log("in"); } } test(); })(); // 为什么这里输出的结果不是out,而是直接报错呢?
在 Chrome 中,块级作用域内的函数声明,会发生提升行为,但请注意这个提升至 IIFE 的 test 是 undefined(这点与起初的认知是稍微有点不同,对吧),这是浏览器 JS 引擎的行为,那使用圆括号去调用 undefined 肯定会报错。还记得在 Safari 14 的时候,这段代码并不会报错,因为提升至 IIFE 的 test 就是一个函数,因此不会报错。当我今天再去试的时候(Safari 15),已经会报错了,表现与当前最新的 Chrome 一致。
test
undefined
另外,在 ES5 规则中,函数只能在全局作用域和函数作用域内声明,而不能在块内声明。注意,这是规则本身就不允许的,但是浏览器厂商在实现的时候,并没有严格遵循这一规定,不同 JS 引擎实现可能有所不同。因此,才会有上述的差异。
总的来说,应遵循这一原则:函数声明请在全局或函数作用域内声明,若在块内,请使用函数表达式。在 ESLint 中专门有一个规则去检查这种情况:no-inner-declarations。
no-inner-declarations
与你疑问相关的,此前我写过一篇文章有提到,有兴趣可以看下:点击这里。
打卡~
文章 0 评论 0
接受
在 Chrome 中,块级作用域内的函数声明,会发生提升行为,但请注意这个提升至 IIFE 的
test
是undefined
(这点与起初的认知是稍微有点不同,对吧),这是浏览器 JS 引擎的行为,那使用圆括号去调用 undefined 肯定会报错。还记得在 Safari 14 的时候,这段代码并不会报错,因为提升至 IIFE 的test
就是一个函数,因此不会报错。当我今天再去试的时候(Safari 15),已经会报错了,表现与当前最新的 Chrome 一致。另外,在 ES5 规则中,函数只能在全局作用域和函数作用域内声明,而不能在块内声明。注意,这是规则本身就不允许的,但是浏览器厂商在实现的时候,并没有严格遵循这一规定,不同 JS 引擎实现可能有所不同。因此,才会有上述的差异。
总的来说,应遵循这一原则:函数声明请在全局或函数作用域内声明,若在块内,请使用函数表达式。在 ESLint 中专门有一个规则去检查这种情况:
no-inner-declarations
。与你疑问相关的,此前我写过一篇文章有提到,有兴趣可以看下:点击这里。
JavaScript 深入之变量对象