锁定老帖子 主题:关于js解析执行有趣的事
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-06-19
malie0 写道 不明白为什么第二个例子去掉function a() {}就能赋值了,后面那个函数是干吗用的,不是之前已经return了吗? 这个是为什么呢 楼主再给详细解释下呗,谢谢
|
|
返回顶楼 | |
发表时间:2012-06-19
《javascript语言精髓与编程实践》第2版第153页 3.2.4.5变量作用域中的次序问题
|
|
返回顶楼 | |
发表时间:2012-06-20
天朗java 写道 malie0 写道 不明白为什么第二个例子去掉function a() {}就能赋值了,后面那个函数是干吗用的,不是之前已经return了吗? 这个是为什么呢 楼主再给详细解释下呗,谢谢
看了下前面的帖子,说说我的理解 var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); 相当于 var a = 1; function b() { a = 10; return; var a; } b(); alert(a); js 解析阶段把a认作了一个局部变量。 |
|
返回顶楼 | |
发表时间:2012-06-20
其实就是一个预编译和执行期的问题。javascript会分块的进行预编译,预编译期会处理所以使用var声明的变量以及使用function的函数会被处理,但var声明的变量只进行索引,而不处理赋值,赋值在执行期处理,而function的函数会处理函数体。
所以第一个例子:预编译期间建立索引foo和处理bar函数体,但foo未赋值,所以foo为undefined。然后执行期给foo赋值1,执行bar()时,先预编译函数体内的内容,建立局部变量索引foo,但未赋值,所以foo=undefined,此时执行期bar(),由上往下执行,结果自然为10. 而第二个例子类似,因为执行期到b()时,会预编译b里面的内容,此时function a(){}相当于(类似)var a,即也建立局部变量的索引a,所以执行期给局部变量的a赋值10,并不影响全局的a |
|
返回顶楼 | |
发表时间:2012-06-20
malie0 写道 不明白为什么第二个例子去掉function a() {}就能赋值了,后面那个函数是干吗用的,不是之前已经return了吗?
JS里有所谓的"预编译"规则,即函数通过如下方式function a()={}定义,会有一个函数上提的过程,可以理解为变量a在函数执行之前就上提到环境的顶部所以a=1其实是修改内部变量a,不是修改外部变量.可以这样验证下 var a = 1; function b() { alert(a); return; function a() {} }; b(); |
|
返回顶楼 | |
发表时间:2012-06-20
是有点绕,所以我们在实际应用中 需要避免这些重名的变量 并且尽量少的使用全局变量
|
|
返回顶楼 | |
发表时间:2012-06-20
第一个大家基本上说了,第二个我是这么理解的,js中不管函数还是变量都是对象,function a()在预编译时,a会覆盖a=10这个a。在使用IDE编辑JS的时候,会提示a=10错误:Type mismatch: cannot convert from int to a()。也就是说在分块预编译的时候,a =10的这个a不再是全局的那个a,而是函数a()。具体细节参考JavaScript-Core-and-Practice里面的作用域链
|
|
返回顶楼 | |
发表时间:2012-06-20
理解了
我也是用 var a = 1; function b() { alert(a); return; function a() {} }; b(); 测了下,就如大家说的在预编译阶段a的值就已经是function a() {}了,是局部变量。也就是js的执行和预编译是分开的,先预编译再执行,所以变量声明可以放在执行之后 |
|
返回顶楼 | |
发表时间:2012-06-20
关于JavaScript预编译与执行顺序的关系,可以看看这篇参考下http://liukemin.iteye.com/blog/1562948
|
|
返回顶楼 | |
发表时间:2012-06-20
第一题如果没有那个var就很好理解了,有了var在局部它就是个undefined,第二题很好理解,上面的全局变量被函数弄成了个局部变量
|
|
返回顶楼 | |