深入理解JavaScript程序设计

今天没事情回顾了一下我在在去年4-6月份学习JavaScript程序设计的笔记。发现书到用时方恨少,简单的太简单,难的不用的看来一会才慢慢看懂。

1.预编译

预编译主要用来解决所有的JavaScrip代码执行顺序的问题。javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”,了解javascript引擎的执行机理,将有助于在写js代码过程中的思路总结。

举个例子来讲解一下(举得例子比较难,不太好懂,但能很好的讲解出预编译的过程):

function test(a){   //在这里a是形参
    console.log(a);   
    var a = '123';  //a在被声明并且赋值
    console.log(a);
    function a(){}; //a在这里被函数声明
    console.log(a);
    var b = function (){
        return '函数b';
    }();
    console.log(b);
}
test(1);

这个例子非常的恶心,他的形参,变量名,函数名用的都是 a,就出现了覆盖执行的问题,下面我们来解决这个问题。

如果是顺序执行会依次打印:1 ,123,function a(){},函数b。实际结果输出的是:function a(){},123,123,函数b。

  

之所以会这样,是因为在预编译的时候执行前上下文规定了它执行的顺序。

预编译主要分为四部:

(1)创立AO对象。在函数上下文中,我们用活动对象AO(activation object)来表示变量对象。

(2)找到形参和声明变量,将变量名和形参名作为AO的属性名。值暂时为undefined。

(3)将实参和形参统一。

(4)在函数体里面找到函数声明,值赋予函数体。

第一步:AO对象建立,AO{ };

第二步:a作为形参出现一次,作为声明变量出现一次。b作为声明变量出现一次。同一个值声明或者作为形参多次我们只写一个。所以现在AO就是:

AO{

  a:undefined,

  b:undefined

}

第三步:将实参和形参统一。实参就是test(1)里面的1,形参是test(a)里面的a,所以现在AO就是:

AO{

  a:1,

  b:undefined

}

第四步:在函数体里面找到函数声明,值赋予函数体。函数体只有a(),所以将函数赋值给a,所以现在AO就是:

AO{

  a:function a(){},

  b:undefined

}

预编译结束,根据AO和页面代码开始执行,所以:

开始执行代码的时候,AO是:
AO{
 a:function a(){},
 b:undefined
}
所以第一次打印是:function a(){};
代码继续执行到var a = '123';
由于预编译已经声明,所以这一行只执行赋值语句 a='123';
所以第二次打印是:123
代码继续执行到function a(){};函数声明已经在预编译执行完毕,不执行
所以第三次打印还是:123
代码继续执行到var b = function (){ return '函数b';}();
预编译已经声明,所以这一行只执行赋值语句 b = function (){ return '函数b';}();
所以第四次打印的是b,b是一个立即执行函数,返回值就是:函数b

结论:预编译能解决所有的代码执行顺序的问题。即使不明白JavaScript的预编译也不太影响,日常对JavaScript的操作,但明白以后会对我们的理解会有很大的帮助。

2.闭包

内部数据保存到外部导致闭包。

3.面向对象的程序设计

猜你喜欢

转载自www.cnblogs.com/liuzhou1/p/10791989.html
今日推荐