关于js解析执行有趣的事

来源:互联网 发布:安卓手机c语言编程软件 编辑:程序博客网 时间:2024/05/01 16:59
Js代码 
  1. var foo = 1;    
  2. function bar() {    
  3.     if (!foo) {    
  4.         var foo = 10;    
  5.     }    
  6.     alert(foo);    
  7. }    
  8. bar();    

 

Js代码 
  1. var a = 1;    
  2. function b() {    
  3.     a = 10;    
  4.     return;    
  5.     function a() {}    
  6. }    
  7. b();    
  8. alert(a);    
 

大家看输出的是什么?

第一题 
10 
第二题 
1(局部和全局变量不同)


解释原因:

1.通俗解释

想简单理解的话,可以想象在第一个例子的函数bar进入时候第一行加一行
var foo = undefined

在第二个例子的函数b的第一行加一个
var a = undefined

解析作用域时候,该作用域里面不管哪行定义了东西,都可以简单想象成第一行声明了一个未初始化的同名变量。
(纯粹为了容易理解)

2.专业解释

这关系到JS解析顺序的问题,当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理。 
做如下处理: 
1. 在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。 
2. 在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined) 

换个角度来说,这个是函数体升迁的问题,如果是用 var fn = function() 这种形式来定义,那么 fn 会升迁,但是函数体不会升迁,因此会报告错误说 fn 不是一个方法(注意不是报告未定义),而如果使用 function fn() 来定义方法,那么 fn 和函数体会同时升迁,这样 fn() 是可以调用到结果的。


转载:http://www.iteye.com/topic/1124618

原创粉丝点击