想请教一下下面的代码中,为什么A函数在执行时,我为A重新赋值为1,可是后面的alert(A)弹出的结果任然显示A为function?而如果A=1改为var A=1,就会弹出1。
另外:一般立即执行的函数都是匿名函数吧,这里让一个非匿名函数立即执行有点诡异啊。。呵呵
<script>
(function A(){
A=1;
alert(A) //显示function A(){..}
})()
function B(){
B=2
alert(B) //2
}
B();
B() //undefined
</script>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
解释请参考
http://segmentfault.com/q/1010000002810093
这个才是正解~~~
第一个问题:
这里涉及到了作用域和作用域链的问题。
第一个函数一创建就会立即执行,分解这个2个过程来看下:
首先是创建过程:
立即执行的函数A乍看起来是在全局环境(
window)下面定义的,实际上是在一个脱离了window的环境下创建的。暂且叫这个环境为env.那么函数A相当于env的一个属性(方法). 这是在函数创建过程中发生的,env属于函数A的[[scope chain]]属性的最底层执行过程
函数A会创建一个活动对象(
call object)属于[[scope chain]]的最高层.它包含了arguments属性,在这里为[],同时还创建了全局变量A,为window的属性。因此在执行过程中首先会从自身的活动对象查找是否有A属性,明显没有。那么往下一层env中寻找,发现了A属性为function A().window对象不在这个作用域链当中。因此最后会输出function A(){}你说的另外一种情况:
这里由于
var A=1;属于定义局部变量,在函数A执行的过程中会给活动对象(call object)附加上属性A,因此console.log(A)获取到的即在活动对象上的属性A=1;所以最后输出1;第二次为什么不能输出暂时没搞明白,明天再想吧。第二个问题:
这里的B现在不是立即执行的函数,那么作用域链的最底层是window对象,你在函数B中定义的全局变量B是能在window对象上访问的到的。所以第一次执行会输出
2.在B()执行完后,会将这个值类型先说一下 A=1; B=2;代表的是 全局变量A B分别赋值1 2 ,另外,函数声明表达式,你可以立即在当前作用域定义了对应的一个变量 并赋值一个函数 第一个A,执行一个表达式,作用域是有个作用域链,局部作用域像全局作用域冒泡,直到找到为止,所以,在匿名函数作用域内,所以A指函数,B最开始应该是函数的,然后被你重新赋值了!结果就为你新的赋值 2 !!!
在 ECMA-262-3 in detail. Chapter 5. Functions 中提到了函数表达式的作用范围
另外在 ECMA-262 的 Runtime Semantics: Evaluation 一节也提到了函数表达式的执行过程。
英文不是很好,所以没有完全找到答案,只能帮你到这里了………
要是我会尽量避免这种搞不清楚的事情
函数表达式中,变量获取的优先级:局部变量>形参>全局变量;这个规律可以很好的解释你上面提到的问题。
楼上都是大虾 。 就说一下战斗力只有5的渣渣的见解
你迷惑不是作用域,而是 有名字的匿名函数 NFE
NFE的特点:
- 你只能内部访问
- 你改不了他名字 除非你定义一个跟他同名的 eg