轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)
2014-04-27 17:15
375 查看
hey,guys!我们一起总结一下JS预解析吧!
首先,我们得搞清楚JS预解析和JS逐行执行的关系。其实它们两并不冲突,一个例子轻松理解它们的关系:
你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解析),但吃的时候还是一口一口的吃(JS逐行执行)!
OK,解决下面五个问题,JS预解析就算过了~~(前提:对JS变量作用域有清晰理解)
一、JS预解析是什么?
其实就是对程序要用到的材料(变量,函数)给一个初始值,并存到一个表中(我自己虚构的),当程序运行到那一行时,就来这个表看有没有初始值,没有就报错~~
二、JS在什么情况下会进行预解析呢?
1.遇到<script></script>标签对时;
2.遇到函数时;(因为变量是有作用域的)
三、JS对什么进行预解析?
1.函数传参的变量
2.var 后面的变量
3.函数
四、那JS会给这些 变量、函数 赋予什么初始值呢?
1.凡是传参,直接赋值参数;
2.凡是var 的,都会赋予一个 undefined 作为初始值;
3.凡是函数,直接赋予 函数本身 作为初始值;(所以这就是为什么我们可以把 函数调用 放到 函数声明 之前的原因)
五、什么情况会改变 预解析 赋予的初始值呢?
有赋值功能的符号:=, +=, -=, *=, /=, ++, --等 (如果还有再添加..)
下面是来点实例:
下面我们再看下这两种情况的区别:
看,JS预解析也就这样,没我们想象中的那么难吧!
欢迎拍砖,觉得好的请点下推荐~~
之前还有一个地方不够严谨,补充一下(2014.06.08):
对于函数内的预解析,可以理解成在执行前一瞬间,传了参数后,进行预解析,然后才执行。
对于参数的预解析,传参前,直接赋值undefined,传参后,就是传参的值;
所以在函数内的预解析 参数 是最先被解析到的。
首先,我们得搞清楚JS预解析和JS逐行执行的关系。其实它们两并不冲突,一个例子轻松理解它们的关系:
你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解析),但吃的时候还是一口一口的吃(JS逐行执行)!
OK,解决下面五个问题,JS预解析就算过了~~(前提:对JS变量作用域有清晰理解)
一、JS预解析是什么?
其实就是对程序要用到的材料(变量,函数)给一个初始值,并存到一个表中(我自己虚构的),当程序运行到那一行时,就来这个表看有没有初始值,没有就报错~~
二、JS在什么情况下会进行预解析呢?
1.遇到<script></script>标签对时;
2.遇到函数时;(因为变量是有作用域的)
三、JS对什么进行预解析?
1.函数传参的变量
2.var 后面的变量
3.函数
四、那JS会给这些 变量、函数 赋予什么初始值呢?
1.凡是传参,直接赋值参数;
2.凡是var 的,都会赋予一个 undefined 作为初始值;
3.凡是函数,直接赋予 函数本身 作为初始值;(所以这就是为什么我们可以把 函数调用 放到 函数声明 之前的原因)
五、什么情况会改变 预解析 赋予的初始值呢?
有赋值功能的符号:=, +=, -=, *=, /=, ++, --等 (如果还有再添加..)
下面是来点实例:
alert(a); //报错,没有var 是不会进行预解析的 a = 0;
alert(a); //undefined var a = 0; alert(a); //0, =号 可以改变初始值
alert(a); //function a(){ alert('我是函数') }, undefined代表空,函数不是空的,当然要不是空的啦! var a = '我是变量'; function a(){ alert('我是函数') } alert(a); //'我是变量', = 可以改变初始值
alert(a); //function a(){ alert('我是函数') }, undefined代表空,函数不是空的,当然要不是空的啦! a++; alert(a); //NaN, ++可以改变初始值 var a = '我是变量'; function a(){ alert('我是函数') } alert(a) //'我是变量', = 可以改变初始值
alert(a); //undefined var a = 0; alert(a); //0 function fn(){ alert(a); //undefined;遇到函数,重新进行预解析 var a = 2; alert(a); //2 } fn() alert(a); //0,fn里面的a与全局的a不是同一作用域的
alert(a); //undefined var a = 0; alert(a); //0 function fn(){ alert(a); //0;因为没var, 所以这里的a会被看作是全局的,往上查找,找到a=0,所以是0,如果全局也没有就会报错 a = 2; alert(a); //2 } fn() alert(a); //2,fn把这全局的a修改了
function fn(a){ alert(a); //undefined,JS会把传参当作var一样对待,相当于在fn内部定义了一个变量--> var a; a = 2; alert(a); //2,这里修改的不是全局的哦,改的是fn的局部变量哦 } fn() alert(a); //报错
<script> alert(a); //报错,因为遇到<script>标签对时,会先对这一块进行预解析,运行到下面的才会再进行预解析,下面没预解析,所以找不到a,于是报错了 </script> <script> alert(a); //undefined var a = 0; alert(a); //0 </script>
<script> var a; </script> <script> alert(a); //undefined,虽然这个<script>标签对没有定义a,但会往上查找,上面的个<script>标签定义了,所以为undefined </script>
下面我们再看下这两种情况的区别:
alert(a); //function a(){ alert('我是函数') } function a(){ alert('我是函数') }
alert(a); //undefined,可以看出,凡是var,初始值都是undefined var a = function (){ '我是函数' }
看,JS预解析也就这样,没我们想象中的那么难吧!
欢迎拍砖,觉得好的请点下推荐~~
之前还有一个地方不够严谨,补充一下(2014.06.08):
对于函数内的预解析,可以理解成在执行前一瞬间,传了参数后,进行预解析,然后才执行。
对于参数的预解析,传参前,直接赋值undefined,传参后,就是传参的值;
所以在函数内的预解析 参数 是最先被解析到的。
function a(b){ //首先,执行的瞬间,传参后进行预解析-> b = 1,然后往下找 b = b函数,最后b = b函数 alert(b); function b(){ alert(b); } b(); } a(1); //b函数, b函数
function a(b){ //传参后进行预解析 -> b = c函数,然后往下找 b = b函数,最后b = b函数 alert(b); function b(){ alert(b); } b(); } a(c); //b函数, b函数 function c(){ return 123; }
相关文章推荐
- 轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)
- 轻松搞定javascript预解析机构(搞定后,一切有关变态面试题都是浮云)
- [置顶] android分享到新浪微博,认证+发送微博,神马'40113token_rejected! Oauth Token不合法'错误,都TMD都是浮云,终于一切搞定!
- 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配)
- 神马都TMD都是浮云,分享发送微博时,报40113的错的解决方法,终于一切搞定!
- 轻松搞定JavaScript预解析
- android分享到新浪微博,认证+发送微博,神马'40113token_rejected! Oauth Token不合法'错误,都TMD都是浮云,终于一切搞定!
- 44 个 JavaScript 变态题解析
- 深入理解javascript原型和闭包(1)——一切都是对象
- WebViewJavascriptBridge机制解析
- 三大秘诀助你轻松搞定JavaScript
- JavaScript中最常见的三个面试题解析
- JavaScript解析机制——学习笔记
- 44 个 JavaScript 变态题解析
- 韩顺平_轻松搞定网页设计(html+css+javascript)_第24讲_js案例讲解_js自定义函数_学习笔记_源代码图解_PPT文档整理
- 深入理解javascript原型和闭包(1)——一切都是对象
- [JavaScript]只需一行代码,轻松搞定快捷留言功能
- JS夯实基础:Javascript 变态题解析 (上)
- JS夯实基础:Javascript 变态题解析 (下)
- 解析Javascript事件冒泡机制