js---07 js预解析,作用域---闭包
js解析器首先不会逐行读代码,这是第二部了。
首先 根据var找到变量,根据function找函数,找到变量var a = 1,js解析器只会读取等号前面的var a,并把a设置值未定义,并不会读取等号后面的a = 1,所以a的值是未定义,并加入仓库,根据function找到函数后,function a (){ alert(2); },找到函数是函数整体,这是js的预解析(预解析只找var 和函数)。遇到重名的留下后面的,变量和函数重名了,函数在后面,只留下函数。
正式读取代码的时候,是从上到下从左到右,上面<script/>块中定义的变量可以直接在下面的<script/>中使用。
alert(a);
var a = 1;
读取到alert(a);时候,因为之前a是未定义,所以这个报错,遇到表达式a = 1,就把之前a是未定义变成1。 var a = 1;
function fn1(){
alert(a);
var a = 2;
}
fn1();
alert(a);
首先预解析找到var a = 1,此时a未定义,和函数,加入仓库(预解析只解析var 和 函数的定义)。
预解析完了,从上到下执行,遇到函数调用fn1(); 函数是一个局部的域,会新开一个局部作用域,遇到域就进行预解析和逐行执行代码,局部预解析时var a 是未定义,局部预解析完了就开始逐行执行代码,alert(a)只会在函数局部域内找a是未定义,var a = 2只是改变局部域中a为2不会改变全局域的a,最后alert(a)弹出1 var a = 1;
function fn1(){
alert(a);
a = 2;
}
fn1();
alert(a);
首先预解析,a是未定义,函数fn1也加入仓库,全局域的预解析完了。下面开始逐行执行代码。var a = 1把仓库中的a改成1,找到函数的定义,这里不动它,然后找到函数的调用fn1(),开始函数局部域的预解析,局部域中没有var 和函数定义,局部域的预解析完了,然后逐行执行函数内部,读到alert(a),在局部域中没有找到a,则会向上级域中去找,找到全局域的a = 1,弹出a = 1,在执行a = 2,局部作用域没有a则找到上级域,把a改成了2,最后弹出2. var a = 1;
function fn1(a){
alert(a); //a是局部域中的仓库中的a,相当于写了var a;
a = 2;
}
fn1();
alert(a);
首先预解析var a = 未定义 ,和函数fn1()加入仓库。
逐行执行代码a = 1,函数调用fn1(),看到参数a,会在函数局部作用域解析a = 未定义,alert(a)弹出未定义,a= 2改变局部作用域中的a的值,最后alert(a),弹出1。 var a = 1;
function fn1(a){
alert(a);//a是局部域中的仓库中的a,相当于写了var a = 1;
a = 2;
}
fn1(a);
alert(a);
全部预解析,a=未定义,函数就是一个函数。
读代码,全局a=1,函数定义不动。函数调用,局部开始新的预解析和逐行读代码,局部没有var 没有function,有参数a,加入局部域的仓库a = 未定义,接下来局部域逐行读代码,首先从参数开始读,a= 1,是从全局前面传进来的,局部作用域的a等于1了,alert(a)弹出1,a=2修改局部作用域的a = 2,全局a没有改变,因为a参数传进来相当于局部域定义了一个新变量a,最后弹出1 function fn2(){
var a = '9999999克拉钻石23456789';
fn3(a);
}
fn2(); function fn3(a){
alert(a); //相当于写了var a = '99923456678';
}
全局解析:把函数fn2()和fn3()加入全局的仓库。
逐行读代码: fn2()调用:
局部解析 var a = 未定义,无函数定义
局部逐行读代码,a = '9999999克拉钻石23456789',函数调用fn3(a),局部域仓库中没有找到fn3()的定义,去全局域中找,找到了,fn3(a)调用开始:
局部的局部解析,参数相当于新定义一个局部变量,a = 未定义
局部的局部逐行执行代码,a = 全局传进来的值9999999克拉钻石23456789,alert(a)
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title> <script>
window.onload = function (){
var aBtn = document.getElementsByTagName('input');
for( var i=0; i<aBtn.length; i++ ){
aBtn[i].onclick = function (){
alert( i ); // 一直是3,因为for执行完之后i一直等于3
//aBtn[i].style.background = 'yellow';
for( var i=0; i<aBtn.length; i++ ){
aBtn[i].style.background = 'yellow';
}
};
}
};
</script> </head> <body> <input type="button" value="按钮1" />
<input type="button" value="按钮2" />
<input type="button" value="按钮3" /> </body>
</html>
全局预处理和执行:
创建全局LexicalEnvironment === window对象,保存全局var 和函数的定义(保存函数名作为变量指向函数),
var f = 5;
g = 6;
function xx(){};
window对象{
f : 未定义
xx : 指向函数
}
g前面没有var ,预处理阶段不会保存到window对象,会报错。 alert(f);//弹出函数体
var f = 5;
function f(){};
---------------------------
alert(f);//还是函数体
function f(){};
var f = 5; 有冲突时后面出现的是函数,则覆盖前面的变量,如果后面出现的是变量,则不能覆盖前面的函数,后面的函数覆盖前面的函数是重新赋值,后面的变量覆盖前面的变量也是重新赋值。
alert(f);//弹出后面的
function f(){alert(2)};
function f(){alert(1)}; alert(f1);//undefined
var f1 = 5;
var f1 = 6; var f1=5;
var f2=6;
alert(f2);//6 alert(f2);//弹出后面
var f2 = 5;
function f2(){alert(1)}; alert(f3);//弹出前面
function f3(){alert(1)};
var f3 = 5; alert(f4);//弹出后面函数
function f4(){alert(1)};
var f4 = 5;
function f4(){alert(2)}; --------------------------------------------- alert(a);//undefined
alert(b);//预处理阶段,b前面没有var,不会加入到Window对象中,报错
alert(f);//函数体
alert(g);//undefined
var a = 5;//执行阶段window对象中a : 5
b = 6;//预处理阶段没有将b加入windown对象中,但是在执行阶段会将加入b : 6到window对象
alert(b);//弹出6
function f(){
console.log('f');
}
var g = function (){
console.log('g');
}
alert(g);//弹出函数体 预处理阶段,window对象
window{
a : undefied
f : 指向函数
g : undefined ////预处理阶段只会保存 g : undefined,后面函数不是声明方式的函数,不会保存在window对象中。 }
执行阶段
window{
a: 5
b :6
f:指向函数
g :指向函数
}
函数预处理和执行:
function f(a,b,c){//参数传递相当于在函数体写了 var a = 1,var b = 2,
alert(a);//弹出函数体
alert(b);// var b = 100;
function a(){
}
}
f(1,2); 函数局部预解析过程中:
局部
{
a : 1 //局部作用域的a ,不影响全局作用域的a,
b : 2 //局部作用域的b ,不影响全局作用域的b,
c : undefined
arguments :
}
执行过程中
{
a : 执行函数的引用 //冲突覆盖变量
b:2 //变量不会覆盖
c : undefined
} -------------------------------------------
function f1(){
function f2(){
b = 100;//函数体中没有通过var声明的变量,会加入到全局window作用域中,window{ b : 10},不是加入到f2和f1函数的局部作用域中,
}
f2();
}
f1();
js---07 js预解析,作用域---闭包的更多相关文章
- JS中的预解析
js预解析对于很多学习web前端开发的新手们很困扰,总是很难搞懂到底是个什么东西,今天零度就为大家简单的分析一下,争取让大家都明白! 首先,看一下下面的代码: alert(a); var a = 1; ...
- JS基础语法---预解析
预解析:就是在解析代码之前 1. 预解析做什么事? 把变量的声明提前了----提前到当前所在的作用域的最上面 函数的声明也会被提前---提前到当前所在的作用域的最上面 举例: function ...
- 第112天:javascript中函数预解析和执行阶段
关于javascript中的函数: 1.预解析:把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前 2.执行 :从上到下执行,但有例外(setTimeout,setInterval,aja ...
- javascript的执行和预解析
很久以前遇到过一个面试题目,的的确确是面试官问我的问题,下面是这个问题的代码部分.由于年少无知,没有回答上,被无情pass了. var u ='hello world'; ;(function(){ ...
- JS作用域概念-预解析规则
// 作用域: // 域:空间.范围.区域…… // 作用:读.写 script 全局变量.全局函数 自上而下 函数 由里到外 {} 浏览器: “JS解析器” 1)“找一些东西” :var funct ...
- [妙味JS基础]第六课:作用域、JS预解析机制
知识点总结 浏览器的解析方法 script 全局变量,全局函数 自上而下 函数 由里到外 "JS的解析器": 1)“找一些东西”:var function 参数 var a=未定义 ...
- 关于js语法中的一些难点(预解析,变量提前,作用域)
******标题很吓人************ 其实就是一个小小的例子 ,从例子中简单的分析一下作用域.预解析和变量提前的概念 <!DOCTYPE html> <html> & ...
- 第06课:作用域、JS预解析机制
从字面上理解----域就是空间.范围.区域,作用就是读.写,所以作用域我们可以简单理解为:在什么样空间或者范围内对数据进行什么样的读或写操作. 看一下代码 alert(a); // 为什么是undef ...
- 14 (H5*) JS第4天 函数、作用域、预解析
目录 1:函数的其他定义 2:函数作为参数 3:函数作为返回值 4:作用域 5:作用域链 6:预解析 7:预解析分段 复习 <script> /* * 复习: * 函数:把一些重复的代码封 ...
随机推荐
- svn服务器的搭建过程 主要为服务端
yum -y install subversion 查看版本信息 svnserve --version 创建svn仓库目录 mkdir -p /var/svn/svnrepos 创建svn仓库 svn ...
- js 实现 水仙花数
水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身.(例如:1^3 + 5^3+ 3^3 = 153) <!DOCTYPE html><html ...
- PullToRefreshListView的刷新和加载的控制
pullToRefresh.setMode(Mode.BOTH); Mode.BOTH:同时支持上拉下拉 Mode.PULL_FROM_START:只支持下拉Pulling Down M ...
- Perceptron Learning Algorithm(python实现)
一.概论 对于给定的n维(两种类型)数据(训练集),找出一个n-1维的面,能够"尽可能"地按照数据类型分开.通过这个面,我们可以通过这个面对测试数据进行预测. 例如对于二维数据,要 ...
- 洛谷P2408 不同子串个数 后缀数组 + Height数组
## 题目描述: 给你一个长为 $N$ $(N<=10^5)$ 的字符串,求不同的子串的个数我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样.子串的定义:原字 ...
- 二叉查找树BST 模板
二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东 ...
- [洛谷P1726][codevs1332]上白泽慧音
题目大意:求一个有向图的最大强连通分量中点的个数,并输出这些点(字典序最小). 解题思路:裸的强连通分量. 数据小,求完强连通分量后排序+vector大小比较即可(vector有小于运算符). C++ ...
- [洛谷P1343]地震逃生
题目大意:有n个点m条单向边,每条边有一个容量.现有x人要分批从1走到n,问每批最多能走多少人,分几批运完(或输出无法运完). 解题思路:一看就是网络流的题目.每批最多能走多少人,即最大流.分几批运完 ...
- Go 语言编程
[课程名称]Go 语言编程 [课程时间]2014年7月30日(周三) 20:50 - 22:00 [课程安排]20:50-21:00 通过邮件地址登录网络课堂 ...
- iOS 一个ViewController上显示2个tableView的方法
1.在StoryBoard上创建2个tableView,并用autolayout约束. 2.在ViewController上拖进来. @property (weak, nonatomic) IBOut ...