作用域、JS预解析机制
2017-09-17 10:58
218 查看
作用域:
域:空间 script、全局变量 全局函数 自上而下 函数:由里往外 作用:读、写
浏览器对JS解析机制:
1:预解析:碰到var function 参数会将这些预存到仓库 2:逐行读代码:表达式 =+-*/% 参数
例子1:
alert(a); //function a(){alert(4);} var a = 1; alert(a);//1 function a(){alert(2);}//函数的声明直接往下读 alert(a);//1 var a = 3; alert(a);//3 function a(){alert(4);}//函数的声明直接往下读 alert(a);//3 alert(typeof a)//number a();//函数调用 仓库已经不存在任何函数了-->相当于3();//会报错 a is not a function
1:预解析:找一些东西 var function 参数(放入仓库) 01:a = 未定义 a = function a(){alert(2);} 注:一旦出现重名的,会只留一个(和上下文没有关系,变量和函数重名,就只留下函数) 02:a = function a(){alert(2);} a = 未定义; 踢出未定义 03:a = function a(){alert(2);} a = function a(){alert(4);} 函数遇到函数根据上下文的关系保留a = function a(){alert(4);}
例子2:
alert(a);//undefined var a = 1; alert(a)//1 function fn1(){alert(2)}
1:预解析:找一些东西 var function 参数(放入仓库) a = 未定义所有的变量在正式运行代码前都提前赋了一个值:未定义 fn1()=function fn1(){alert(2)} 2:逐行读代码(从仓库读取) //var a function fn1(){alert(2)}函数声明 //a=1表达式 +-*/%++--! Number()参数; 做一些改变的动作
例子3:
var a = 1; function fn1(){ alert(a);//undefined var a = 2; } fn1(); alert(a);//1
1:预解析: a = 未定义 fn1 = function fn1(){alert(a);var a = 2;} 2:逐行读代码: a = 1; 遇到函数声明直接跳 遇到函数调用再次触发预解析: 01:预解析: 碰到var 定义变量 a = 未定义 02:读代码: 优先的从局部范围内查找有没有定义一个a的值
例子4:
var a = 1; function fn1(){ alert(a);//1 a = 2;//修改全局的a } fn1(); alert(a);//2
1:预解析: a = 未定义 fn1 = function fn1(){alert(a); a = 2;} 2:逐行读代码: a = 1; 函数声明直接跳 遇到函数调用再次触发预解析: 01:预解析:没有var function 参数直接读代码 02:读代码: 优先的从局部范围内查找有没有定义一个a的值 如果没有会顺着子级作用域往父级作用域找(作用域链)
例子5:
var a = 1; function fn1(a){ //function fn1(var a;){ alert(a);//undefined a = 2; alert(a);//2 } fn1(); alert(a);//1
1:预解析: a = 未定义 fn1 = function fn1(){alert(a); a = 2;alert(a);} 2:逐行读代码: a = 1; 函数声明直接跳 遇到函数调用再次触发预解析: 01:预解析: 参数本质上就是局部变量var a a= undefined 02:读代码: 根据就近原则里面有个a = undefined
例子6:
var a = 1; function fn1(a){ //function fn1(var a = 1){ alert(a);//1 a = 2; } fn1(a);//里面的参数来自全局 alert(a);//1
1:预解析: a = 未定义 fn1 = function fn1(a){alert(a); a = 2;} 2:逐行读代码: a = 1; 函数声明直接跳 遇到函数调用再次触发预解析: 01:预解析: 参数本质上就是局部变量var a a= undefined 02:读代码: 从参数开始读 全局上的a = 1赋值给局部变量a;
调用局部函数
01:通过全局变量var num = 0; function fn1(){ num++; } function fn2(){ num--; } fn2(); fn1(); fn2(); alert(num)//-1
//想要获取fn1内部a的值,定义一个全局变量str var str = ""; function fn1(){ var a = "快获取我"; str = a; } fn1(); alert(str);
02:通过局部的函数调用来获取
function fn1(){ var a = "快获取我"; fn2(a); /* 代码读到这块的时候,代码先读取的是fn2;然后在这个fn1里面查找,如果没找到就会返到父级进行查找,这时候父级已经把fn2给预解析里面了,所以就是说函数fn1里面可以调用fn2 */ } function fn2(a){ alert(a); } fn1();
for嵌套函数中的i取值
<!-- html代码片段 --> <input type="button" value="按钮1" /> <input type="button" value="按钮2" /> <input type="button" value="按钮3" />
window.onload = function(){ var aBtn = document.getElementsByTagName("input");//局部 /*var i=0; function(){ alert(i);//3 //aBtn[i].style.background = "yellow"; }*/ for(var i=0;i<aBtn.length;i++){ aBtn[i].onclick = function(){ alert(i);//undefined //aBtn[3].style.background = "yellow";会报错 for(var i=0;i<aBtn.length;i++){ //i :0 1 2 aBtn[i].style.background = "yellow"; } } } }
第一种情况:这种情况下由于for的执行速度大于btn的点击事件,所以当btn触发点击的时候for已经走完,此时i的值就是btn.length btn点击触发函数的作用域,开始预解析和逐行解读代码内部没有var 不存在i这个变量会往父级查找,父级i=3,所以会弹出3,并且还会报错
for(var i=0;i<aBtn.length;i++){ aBtn[i].onclick = function(){ alert(i);//3 aBtn[i].style.background = "yellow";//会报错 //aBtn[3].style.background = "yellow"; } }
第二种情况:btn点击函数体内再嵌套一层for,此时外层的for已走完,外层i=3,点击的时候触发作用域,触发预解析和逐行读代码;找到内层for循环里的var i 预解析成i=undefined,所以此时弹出的i为undefined
for(var i=0;i<aBtn.length;i++){ aBtn[i].onclick = function(){ alert(i);//undefined for(var i=0;i<aBtn.length;i++){ //i :0 1 2 aBtn[i].style.background = "yellow"; } } }
第三种情况:btn点击函数体内再嵌套一层for,此时外层的for已走完,外层i=3,点击的时候触发作用域,触发预解析和逐行读代码;预解析时没有找到var,表示里面不存在i这个变量,会返回到父级查找,此时的父级外面的i是3,所以此时弹出的i就是3
for(var i=0;i<aBtn.length;i++){ aBtn[i].onclick = function(){ alert(i);//3 for(i=0;i<aBtn.length;i++){ //i :0 1 2 aBtn[i].style.background = "yellow"; } } }
相关文章推荐
- js学习笔记6----作用域及解析机制
- js学习小结(五)2014.4.28(JS预解析机制)
- JS解析机制
- js 函数的执行环境和作用域链的深入解析
- 4 js面向对象基础 - 预解析,词法作用域,作用域链
- js中三种函数的效率、解析顺序、作用域问题解决
- JS解析机制
- js中的预解析(变量提声)、作用域链、闭包机制
- 关于JS解析机制、作用域的一些总结
- Js中的预解析机制与定义函数的三种方式
- JS的解析机制
- js的解析机制
- JS作用域和this机制
- 熟练掌握js中this的用法,解析this在不同应用场景的作用
- JS的解析顺序和作用域(严格模式)
- JS作用域闭包、预解释和this关键字综合实例解析
- JS的解析机制(作用域、变量提升等)和两个例子
- JS的解析顺序和作用域(严格模式)
- JS作用域深度解析
- 深入解析JavaScript框架Backbone.js中的事件机制