javascript编译器的一些原理——变量提升

有没有发现在写代码的时候,往往会遇到一些莫名其妙的错误,然后时间紧急不得不去网上查阅一些代码。虽然要实现的功能解决了,但是看被拷贝的代码好多真心看不懂,以后遇到诸如此类的问题,如果查阅不到这些代码的话还是不会。所以今天给大分享一下内部原理的问题

1.js编译器编译的几条基本原则

a.js预编译:优先解释函数声明,忽略表达式;
b.运行期间:获取变量顺序,由底层向顶层依次查找,直到找到为止。;
c.变量的定义:会被提前到所属代码作用域最前面
d.function foo(){}这种声明会被js编译器解释成var foo;foo = function(){}这种格式

是不是看了几条规则,不知道我说的什么。没关系,可能是我总结的不好,看下面例子具体了解下

2.自执行函数/闭包

自执行函数,相信大家都接触过。如果不知道,应该只是不知道这个学名而已,在此不给出具体文字定义。
简单解释为:类似(function(){...})()这种形式的代码就叫做自执行函数,又称闭包他在js编译器解析到时,直接被执行。

一个简单小例子:

(function(){
    //...
})()

可以被自执行,写成

function(){
    //...
}()

可以被自执行吗?
答:不可以!

这里是因为上面所说规则a :优先解释函数声明,忽略表达式

js预编译时,先解释函数声明,因此function(){...}()前面的function(){...}在‘预编译阶段’已经被解释成变量。js会跳过这段代码,遇到了后面的(),会试图去执行()里的内容,显然不科学;
(function(){...})()则可以被自执行。因为它加了括号,已经变成了表达式。‘js预编译时’会运行它,并对它求解得到一个返回值。而此处返回值是一个函数,故而遇到最后面的()便会执行

例子:

a=1;
console.info(a)
function b(){
   console.info(a);
   var a=10;
   console.info(a);
};
b();//1,undefined,10

你是不是预期结果是1,1,10

这里正是因为上面的规则c :变量的定义会被提前到所属代码作用域最前面

当js编译器,在执行这个b函数的时候。会把它‘body’里面的声明变量,提前到最前面进行声明。如:var a=10; 编译器先会在‘body’最前面进行var a 声明(变量提升)。

上面代码等同于下面代码:

a=1;
console.info(a)
function b(){
    var a;
   console.info(a);
   a=10;
   console.info(a);
};
b();

声明a的时候还没有值,故而打印undefined;

再看一个例子…
  
    

a = 1;
function b(){
    a = 10;
    return;
    function a(){};
};
b();
console.info(a);//1

你是不是预期结果是10,以为会覆盖全局变量?

这里是因为上面的
规则b :运行期间,获取变量顺序,由底层向顶层依次查找,直到找到为止
规则d function foo(){}这种声明会被js编译器解释成var foo;foo = function(){}这种格式

上述代码等价于

a = 1;
function b(){
    var a;
    a = 10;
    return;
    a = function(){};
}
b();
console.info(a);

3.使用场景

有了上面的理论知识,可以解决曾经有人问我的一个问题:三元表达式后面,如何执行多条语句?其实答案就是在后面写自执行函数。当然,不排除有其它方法,代码如下:
    

var a = 2 > 1 ?
    (function(){ var c = 2, d = 1; return c + d; })()
    : (function(){ var c = 2, d = 1; return c - d; })();
console.info(a);//2

这种需求应该很少吧。我宁愿写个if,不过可以实现,呵呵…

author: jyjin
date: 2014.8 [博客搬家]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值