javascript编译器的一些原理——变量提升
来源:互联网 发布:js json添加元素 编辑:程序博客网 时间:2024/05/16 09:44
有没有发现在写代码的时候,往往会遇到一些莫名其妙的错误,然后时间紧急不得不去网上查阅一些代码。虽然要实现的功能解决了,但是看被拷贝的代码好多真心看不懂,以后遇到诸如此类的问题,如果查阅不到这些代码的话还是不会。所以今天给大分享一下内部原理的问题
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 [博客搬家]
- javascript编译器的一些原理——变量提升
- JavaScript—变量提升
- JavaScript—变量提升、函数提升
- JavaScript——变量提升
- javaScript的变量提升
- JavaScript笔记——函数、变量的提升
- Javascript变量提升的问题
- javascript那些事儿——提升:零散变量问题
- javascript性能提升——巧用局部变量
- Javascript中的预解释——变量提升
- 注意javascript变量声明提升的陷阱
- JavaScript 的加载和变量提升
- JavaScript的那些坑之变量提升
- 关于JavaScript变量提升的理解
- javaScript的作用域和变量提升
- javascript的变量提升和作用域
- JavaScript的作用域和变量提升
- js编译器的一些简单原理
- struts解压后的各个文件夹的作用
- Ubuntu14.04下Python集成开发环境Anaconda安装配置
- 链表——删除指定元素
- 原码反码补码和python中的按位运算易混点
- 关系型数据库和非关系型数据库的特性以及各自的优缺点
- javascript编译器的一些原理——变量提升
- 技术人的充电时刻,24个精彩研发案例在等你
- MFC中将一个Button控件失效的方法
- 如何转载别人的csdn博客
- java应届生面试总结
- hdu 3037 Saving Beans (卢卡斯定理)
- Android开发中的@Override-奔跑的皮皮熊
- Nodejs 初步尝试
- 【并查集跳跃访问+树状数组】2017.3.1杂题:[平方根]题解