早些时候在社区看到一个帖子,询问了一个关于 f = ?
的问题,今天又想起这个问题了,特意上来问一下,看看有没人可以解答疑惑的。
原题:
(() => {
{
function f () { 'A' }
f = 1;
f = 2;
function f () { 'B' }
f = 3;
}
console.log('f =', f);
})();
// logs f = 2
打了断点大概知道是因为作用域被修改了,但是不清楚为什么第二次函数声明会影响变量f
的作用域。
后来有一个人提到说是:
比较反常识的是函数声明,可以看到函数声明的时候其实只把当前块内作用域的f
复制一份放到函数块内,第一次和第二次函数声明都是这样的,如果当前块内作用域块内没有f
,那么就会在当前块内作用域声明一个f
变量,再把函数赋值上去,紧接着再把块内的f
复制一份到函数块内作用域。
这种问题别研究了
改了一下尝试在ie下执行(ie11还是不支持箭头函数)
win 10 ie11的结果为
f = function f () { 'B' }
win 10 ie11用ie10兼容模式跑结果为
f = 3
使用browserstack测试chrome 30/firefox 30/safari 9.1跑结果为
f = 3
chrome/firefox/safari最新版测试,结果为
f = 2
具体原因就是非严格模式下block statement里函数声明的表现比较奇葩
这种问题真的不值得研究
https://stackoverflow.com/que...
如果我没理解错的话,应该是下面这种执行逻辑
在es6标准下应该是一个确定的结果(f = 2)
其他乱七八糟的结果应该是属于没有实现es6标准的浏览器(es5浏览器)的行为,根据文章所说,es5标准下在block statement中声明function是undefined behavior
在chrome控制台运行下面的代码也可以看到整段代码的执行中变量的变化过程,和上面分析的是一致的
↑这个时候右键点右边的
Block -> f: f()
选择show function definition可以知道这个函数是function f(){ 'B' }
↑此时
Local -> f: f()
为function f(){ 'B' }