前言

承接在上文的script标签的使用之后,展开对js的执行进行了解(在工作的现阶段只会对js进行接触,所以首先对js进行了剖析)。

详解

js的作用域

1、在js语言中,没有类似于c语言这样的块级作用域。

2、js语言中的顶级作用域为window对象范围内,称为全局作用域,在全局作用域中声明的变量为全局变量。

3、js函数范围内的变量只能在函数内部使用,函数外部无法使用,这样的变量为局部变量。

4、js函数可以嵌套,多个函数的嵌套构成了作用域的层层嵌套,这称为js中的作用域链。

5、js作用域链变量访问规则:

(1)、当前作用域内存在要访问的变量时,则使用当前作用域中的变量。

(2)、当前作用域中不存在要访问的变量时,则会到上一层作用域中寻找,直到全局作用域。

JavaScript是一种描述型脚本语言,由浏览器进行动态的解析与执行。函数的定义方式大体有以下两种,浏览器对于不同的方式有不同的解析顺序。

//“定义式”函数定义
Fn1();
function Fn1(){
alert("Hello World!");
}
//“赋值式”函数定义
Fn2();//warnning Fn2 is not a function
var Fn2 = function(){
alert("Hello wild!");
}

页面加载过程中,浏览器会对页面上或载入的每个js代码块(或文件)进行扫描,如果遇到定义式函数,则进行预处理(类似于C等的编译),处理完成之后再开始由上至下执行;遇到赋值式函数,则只是将函数赋给一个变量,不进行预处理,待调用到的时候才进行处理。(像上一个代码块里面的定义式函数体,不会存在问退,不像一般的C/C++中必须是先声明之后才可以调用,因为在js中执行的时候事先会进行扫描,在扫描的过程中就已经进行了预编译,所以在语句的执行顺序上不会存在问题。但是在赋值式定义的时候就不行了。)

代码块及js文件的处理

“代码块”是指一对标签包裹着的js代码,文件就是指文件啦,废话:D
浏览器对每个块或文件进行独立的扫描,然后对全局的代码进行顺序执行(2中讲到了)。所以,在一个块(文件)中,函数可以在调用之后进行“定义式”定义;但在两个块中,定义函数所在的块必须在函数被调用的块之前。

<script type="text/javascript">
Fn();// warnning:Fn is notdefined,两个块换过来就对了
</script>
<script type="text/javascript">
function Fn(){
alert("Hello World!");
}
</script>

注意:重复定义的函数会被后面的函数覆盖

body的onload函数与body内部函数的执行

//html head...
<script type="text/javascript">
function fnOnLoad(){
alert("I am outside the Wall!");
}
</script>
<body onload="fnOnLoad();">
<script type="text/javascript">
alert("I am inside the Wall..");
</script>
</body>
//先弹出“I am inside the Wall..”;
//后弹出“I am outside the Wall!”
//body的onload事件触发条件是body内容加载完成,而body中的js代码会在这一事件触发之前运行

 

javascript的回调函数

对于javascript严格来说,JavaScript是没有多线程概念的,所有的程序都是“单线程”依次执行的。
function fn1(){

setTimeout(function(){
alert("我先调用")
},1000);
}
function fn2(){
alert("我后调用");
}
fn1();
fn2();
// 先弹出:“我后调用”,
// 1秒后弹出:“我先调用”

for(var i=1;i<=3;i++){
  setTimeout(function(){
    console.log(i); //输出:4,4,4
  },0)
}

看上去,fn2()和延时程序是分两个过程再走,但其实,这是JavaScript中的“回调”机制在起作用,类似于操作系统中的“中断和响应” —— 延时程序设置一个“中断”,然后执行fn2(),待1000毫秒时间到后,再回调执行fn1()。

再上面的样例2中可以很明显的看到显示的是444,就是因为在在设置函数setTimeout的时候先进入线程的是for循环,所以这个for循环会先执行玩之后在执行setTimeout函数。(将for循环单独设置为一个函数的话就可以解决这个问题。)
同样,body的onload事件调用的函数,也是利用了回调机制——body加载完成之后,回调执行fnOnLoad()函数。
最常见的回调就是onclick、onmouseo教程ver、onmousedown、onload等等浏览器事件的调用函数;还有Ajax异步请求数据的处理函数;setTimeOut延时执行、setInterval循环执行的函数等。

参考文章:
http://www.jb51.net/article/36755.htm