javascript预编译

  js作为一本脚本语言,可以不经过编译直接运行,但遇到预编译的问题,尤其是变量或函数同名时,这点知识就尤其必要了。

  理解预编译首先要弄清楚两种概念:函数声明和变量赋值。

function fun(){ }//函数声明

  这种形式的写法是函数声明,即声明一个函数,脚本在执行之前会做预编译处理。

var fun= function(){ }//变量赋值

  这种写法是变量赋值,函数在js语言里也是一种数据,匿名函数作为变量赋值给定义的变量。这种形式在预编译处理阶段,只会给变量ledi分配一个内存空间,不会做初始化。初始化过程中会在执行时执行。

 

  <script><script/>也可看做一个函数,那么它执行前同样进行预编译,与执行函数前预编译四部曲步骤差不多,但它没有形参和实参,就少了一些步骤,但也有不同之处,就是它此时创建不是AO对象了,具体如下:

1.创建GO对象(global object)即window;

2.查找全局变量,将变量名作为window的属性,赋值为undefined(注:未声明就赋值的变量,即隐式变量,也是全局变量);

3.在<script><script/>内查找函数声明,函数名作为全局对象的属性,值为函数引用;

当变量名与函数名相同时,AO或GO内只建一个属性名;

 

预编译:
函数的预编译发生在执行函数之前。
预编译四部曲:
1.创建AO对象;
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined;
3.将实参值和形参统一;
4.在函数体里面找函数声明,值赋予函数体。

预编译完在之后,就要执行函数了:

function fun(){ 
alert('1'); 
};  
fun(); 
function fun(){ 
alert('2'); 
}; 
fun();

  这段代码,首先判断两个都属于函数声明。都会在预编译阶段处理,而函数名相同,会按后定义的来定义函数,在执行阶段只会看到后定义的函数结果,也就不难理解了。

  结果就是 alert('2') 会被执行。

var fun = function(){
alert('1');
} fun(); fun = function(){
alert('2');
} fun();

 这段代码,首先判断两种都属于变量赋值。在预编译阶段,两个变量名一样,分配一个内存空间存放变量fun内容。当代码执行时,按照顺序执行和赋值,会先后得到两种结果。

 

1 function fun(){alert('1');}; 
2 fun(); 
3 fun = function (){alert('2');}; 
4 fun();

这段代码,首先判断,前一种属于函数声明,后一种属于变量赋值。预编译处理完,首先执行第二行,实际上是第一行的内容,第三行相当于将fun变量重新赋值即初始化,重新赋值后,第四行执行第三行的函数。

window.alert(fun);
function fun(){
}
window.alert(fun);
var fun = 123;

 以上代码分开执行,可验证,函数预编译会执行,变量赋值则是先分配空间,执行时再赋值。

 

下面给大家一些实例讲解:

function bar(){
return foo;
foo=10;
function foo(){}
}
console.log(bar());

该函数的返回值为function foo(){ }。

 

立即执行函数
在函数后添加“()”,执行完即被销毁。
写法:( function ( ) { … } ( ) )或 ( function ( ) { … } ) ( )

(function (){ var a = 123; var b = 234; console.log(a+b); }())
立即执行函数也可以引入参数。

(function (a,b,c){
console.log(a+b+c)
}(1,2,3))

此时输出值为6。

注:1)只有表达式才能被执行!!!

var demo=function(){
console.log('a');
}();

执行一次后demo已不是函数。
2)若在函数申明后加执行符号()会报错。
3)正负号+ - 和非 ! 会将后面的东西变成表达式!!!
---------------------
需要注意的是在预编译中,是先创建GO对象,再创AO对象,当执行代码时,AO、GO都有同一属性名时,要看执行代码的作用域,是全局就使用GO,是局部就使用AO,若AO内没有,而又是局部域,就可向GO对应的值。

posted @ 2018-12-17 20:31  帅帅鼠标  阅读(222)  评论(0编辑  收藏  举报