请教一个预编译的问题

2019-05-22 22:19:40 +08:00
 kuanng

网上说预编译的最后一步几乎都是:找到函数声明,将函数名当作 AO 对象的属性,对应属性的值为函数体。

按照这样的理解,下面的调用 bar 肯定是成功的。

function foo() {
  bar() 
  function bar() {}
}

foo()

稍微修改一下。

function foo() {
  bar() //bar is not a function
  {
    function bar() {}
  }
}

foo()

如上所示,bar 的值不是一个 function,而是 undefined。

为什么 bar 是 undefined ?

3216 次点击
所在节点    JavaScript
11 条回复
littlewing
2019-05-22 22:33:22 +08:00
是不是作用域的问题?
secondwtq
2019-05-22 22:35:35 +08:00
这跟预编译有什么关系么 ...
kuanng
2019-05-22 22:40:09 +08:00
@secondwtq 那请教一下是什么问题呢?
bestie
2019-05-22 22:52:21 +08:00
你这是作用域的问题。。和预编译有啥关系
kuanng
2019-05-22 22:54:27 +08:00
@littlewing 如果是作用域的问题,那么下面这段代码也一定是错的
function foo() {
{
function bar() {}
}
bar()
}

foo()
但是它却是运行成功的
VDimos
2019-05-22 23:03:25 +08:00
脚本语言哪来编译一说
autoxbc
2019-05-22 23:03:25 +08:00
对于已经实现 ES6 的浏览器,在块级作用域中的函数声明是有些混乱的,具体可以看教程

https://es6.ruanyifeng.com/#docs/let#%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F%E4%B8%8E%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E

关键的部分摘录如下

允许在块级作用域内声明函数。
函数声明类似于 var,即会提升到全局作用域或函数作用域的头部。
同时,函数声明还会提升到所在的块级作用域的头部。

按照我的理解,题目中的代码,实际是按照这样解析

function foo() {
var bar
bar()
{
bar = function () {}
}
}

foo()

原则上,为了避免歧义,应该彻底弃用函数声明,一律用函数表达式
kuanng
2019-05-22 23:35:55 +08:00
@autoxbc 感谢
aaniao002
2019-05-23 01:45:49 +08:00
var bar= () =>
KuroNekoFan
2019-05-23 08:10:32 +08:00
function 定义和 var 都会带来变量提升,此题终结
redbuck
2019-05-23 11:12:24 +08:00
ES6 添加了块级作用域,所以你用{}包起来就有了一个私有的作用域.

如果你在 ES5 环境中(IE8 以下)应该不会报错

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/566738

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX