预解释-基础
预解释(变量提升):在当前的作用域中,JS代码从上到下执行之前,浏览器会默认的先把所有带var/function关键字的进行提前的声明或者定义对带var变量的是提前声明(declare)对带function关键字的是提前定义(声明+定义)(defined)
->在预解释阶段,带var关键字的只是提前的声明,只有在JS从上到下执行的过程中才会进行定义赋值:
1//->预解释阶段:告诉浏览器在当前的作用域中(window)有一个名字叫做num的变量:varnum;2console.log(num);//->undefined(只有声明没有定义的默认值是undefined)3varnum=13;//->num=13;(定义:给变量赋值num=13)4console.log(num);//->13
->在预解释阶段,带function关键字的,声明+定义两部分都完成了:
1//->预解释阶段:fn=xxxfff000(xxxfff000是一个内存地址)2console.log(fn);//->函数本身functionfn(){console.log("ok");}3functionfn(){4console.log("ok");5}//->3-5行代码在预解释阶段已经声明加定义了,以后代码执行的时候在遇到也不会重新进行操作,直接跳过这几行就可以了6console.log(fn);//->函数本身functionfn(){console.log("ok");}
->预解释只发生在当前的作用域中,开始的时候只对window作用域下带var/function关键字的进行预解释,而函数体中出现的带var/function关键字的这些代码此时还都是一堆字符串呢(没有实际意义),所以开始的时候函数体中带这些关键字的都不需要管只有全局代码执行到函数执行的时候,才会形成一个新的私有作用域,在新的私有作用域中:首先给函数的形参赋值,其次是私有作用域中的预解释:把私有作用域中带var和function关键字的进行提前的声明或者定义,最后才是私有作用域中的代码从上到下执行
1//首先是window作用域下的预解释:varn;vars;functionfn=xxxfff000;2console.log(n,s);//n->undefined;s->undefined3varn=9;//全局作用域下的n=9;4vars="str1";//全局作用域下的s="str1";5functionfn(){6 console.log(n,s);//n->undefined;(这个是fn私有作用域的n)s->str1;(这个是全局作用域的s)7 n=7;//定义私有作用域下的n=7;8 s="str2";//定义全局作用域下的s="str2";9 varn=6;//定义私有作用域下的n=6;10}11fn();12console.log(n,s);//此时输出的都是全局作用域的:n->9;s->str2;
->作用域链的问题:在私有作用域中,JS代码从上到下执行,如果遇到了一个变量,首先看是否是自己私有的变量,如果是私有的,那么我们接下来的所有操作(获取值,修改值...)都是用的自己私有的,和外面没有任何关系如果不是自己私有的,则去当前作用域的上一级作用域中查找,如果上一级有,那么接下来操作的,都是在操作上级作用域中的变量;如果上级也没有,则继续向上查找,一直找到window为止如果找到window还没有?如果是变量=值相当于给window下增加一个属性名和属性值:如果是console.log(变量)获取值,会报错
->如何看变量是否为私有的:首先看是否为形参然后看是否在私有作用域中声明过(看有没有带var)两者有其一,就是自己私有的变量;如果两个都不是,就不是私有的,按照上述的作用域链原理来进行查找
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。