---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