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