现在的位置: 首页 > 综合 > 正文

js代码执行及初始化顺序(用var与不用var的区别)

2017年12月27日 ⁄ 综合 ⁄ 共 3122字 ⁄ 字号 评论关闭

---js代码执行顺序:

链接: http://www.cnblogs.com/v10258/archive/2013/04/25/3042248.html

链接: http://www.cnblogs.com/calmwaterflowsdeeper/p/3282331.html#function-variables

1 HTML文档流顺序执行JavaScript代码

         JavaScript代码在装载时的执行顺序也是根据脚本标签<script>的出现顺序来确定的。

         如果通过脚本标签<script>的src属性导入外部JavaScript文件脚本,那么它也将按照其语句出现的顺序来执行,而且执行过程是文档装载的一部分。不会因为是外部JavaScript文件而延期执行。

2 按块执行JavaScript代码,改变js代码执行顺序

         JavaScript解释器在执行脚本时,是按块来执行的。所谓代码块就是使用<script>标签分隔的代码段

         JavaScript解释器如果遇到第一个<script>代码块,则JavaScript解释器会在这个代码块加载完后,先对该代码块进行预编译然后再执行;接着才准备好处理下一个代码块。所以如果在前一个JavaScript块中调用后面块中声明的变量或函数就会提示语法错误。

         如下面代码中,当JavaScript解释器执行第一个代码块时就会提示语法错误,显示a is not defined,f is not defined

         虽然说,JavaScript是按块执行的,但是不同块都属于同一个全局作用域,也就是说,块之间的变量和函数是可以共享的。

         如下代码中,如果将两个代码块位置交换后,数据就可以共享,也就可以执行了。

<scripttype="text/javascript">
   // JavaScript代码块1
   alert(a);
   f();
</script>
<scripttype="text/javascript">
   // JavaScript代码块2
   var a = 1;
   function f() {
       alert(1);
    }
</script>

         如上代码,也可另作修改。当文档流加载完毕,如果再次访问就不会出现undifined错误。修改如下:

<scripttype="text/javascript">
// JavaScript代码块1
window.onload = function(){        // 页面初始化事件处理函数
   alert(a);
   f();
}
</script>
 
<scripttype="text/javascript">
// JavaScript代码块2
var a =1;
function f(){
   alert(1);
}
</script>

   注:以上修改是改变javascript执行顺序的一种方式,称为借助事件机制改变JavaScript执行顺序。另外,还可以通过各种交互事件来改变JavaScript代码的执行顺序,如鼠标事件、键盘事件及时钟触发器等方法。

---[JS的编译期和执行期]:

1、预编译期: 

·        1. 扫描var声明的全局变量和局部变量或函数表达式,初始值为undefined,但不进行赋值操作(这样那个变量就不是 not defined 了)

          2.
注意没有用var声明的全局变量是在执行期才进行defined,在预编译期时不会被创建,如果调用则报错:xx is not defined

·        3.扫描函数声明,如:function f(){..}进行初始化,放置到全局变量中,可以在没有到执行期的时候预先进行调用

         4.注意如果js的函数不是用这种方式进行声明,而是采用类似var f=function(){...}这样的方式进行赋值的话,在预编译期是不会创建的,不能被预先调用,而也是等到执行期才进行初始化函数。

2、执行期: 

·        按照代码顺序,当代码执行到时,才对变量进行赋值。

---[全局变量用和不用var声明的区别:]

1、如果变量用var声明,然后在还没到初始化阶段就提前调用,则JavaScript解释器会认为该变量已经defined,然后使用默认值undefined。

2、如果变量是没有用var声明而是直接赋值的,则js不会在编译期创建变量,如果提前调用会报错: xx is not defined

·      

alert("b" in window) // false, there is no window.b
alert(b) // error, b is not defined

b = 5
alert(a);   //返回值undefined
var a =1;
alert(a);   //返回值1

变量初始化过程发生在执行期,而不是预编译期。

当JavaScript引擎解析脚本时,它会在预编译期扫描所有var声明的变量和函数声明,变量在这个时候就会在window中,初始值为undefined。

f();    //调用函数,返回语法错误
var f = function(){ //函数表达式,不用与函数声明的方式
    alert(1);
}

上面示例中定义的函数仅作为值赋值给变量f,所以在预编译期,JavaScript解释器只能够为声明变量f进行处理,而对于变量f的值,则必须等到执行期才会进行函数初始化,所以提前调用就会出现语法错误,Property
'f' of object [object Object] is not a function

Test demo:

for(var i=0; i<5; i++) { } 
//在循环中声明变量很方便,但不要认为循环之后变量就不存在了,不要把循环当作其scope

alert(i) // 5, variable survives and keeps value
//情形一:
if ("a" in window) {
    var a = 1
}
alert(a)//1
//情形二:
if ("a" in window) {
    a = 1
}
alert(a) //a is not defined(a没有用var声明,在预编译期没有被扫描为window中的undefined)
function test() {
  
  alert(window)

  var window = 5
}
test();//undefined
alert("a" in window) // true, because window.a exists
alert(a) // undefined, because assignment happens below
alert(f) // function, because it is Function Declaration
alert(g) // undefined, because assignment happens below

var a = 5  

function f() { /*...*/ } 
var g = function() { /*...*/ }
var a = 5  
var g = function() { /*...*/ } 

alert(a) // 5
alert(g) // function
alert("b" in window) // false, there is no window.b
alert(b) // error, b is not defined

b = 5

---[全局变量用和不用var声明的区别:]

在执行期,JavaScript解释器是按着代码先后顺序进行解析的,如果在前面代码用了var声明a不过还没有到初始化阶段就调用,则JavaScript解释器会使用默认值undefined。在执行期进行变量的初始化,所以后来是1。

如果变量是没有用var声明而是直接赋值的,则js不会在编译期创建变量,如果提前调用会报错: xx is not defined

抱歉!评论已关闭.