一、何为预解析
JS当中,代码执行前都是需要对带var关键字和function关键字进行预解析。
我们先介绍两个概念: 声明(declare) 和 定义(defined)
声明:就是浏览器引擎分配一个地址,但是并没有分配内存空间 默认值为undefined
定义:分配到内存空间,可以存储。
在预解析当中,首先对window全局作用域下解析,对带var关键字和function关键字进行提前。但var和function还是有区别的
预解析中var只是声明,而function是声明和定义
所以:代码执行的时候,变量要var赋值后才能使用,要不然就是undefined,而function可以任意位置:
如:
1 console.log(num); //undefined 2 var num = 20; 3 console.log(num); //20 4 fn(); //我是一个函数 5 function fn() { 6 console.log('我是一个函数'); 7 }
当然在函数没有执行前,对函数里面的var关键字和function关键字不会进行预解析,只有当函数执行的时候,就会对函数作用域进行预解析,而这作用域是私有作用域,和全局作用域是不在同一作用环境下的。还是看代码吧
console.log(num); //undefined var num = 20; console.log(num); //20 fn(); //30 function fn() { var num=30; console.log(num); } console.log(num);//20
当然,这里可以是带var ,而如果代码中没有带var 而是 num=30,那么函数在自己的作用域中没有找到变量 那么函数会向上一级作用域找这个变量,而如果这个变量上级作用域没有,那么继续向上查找,直到window作用域,这就是作用域链,而如果一直找不到就会报错。
console.log(num); //undefined var num = 20; console.log(num); //20 fn(); //30 function fn() { num=30;//他会向上级作用域查找num这个变量 console.log(num); } console.log(num);//30
作用域中分全局作用域和私有作用域,而私有作用域只有在函数中才能形成封闭的私有作用域。
备注:浏览器引擎在预预解析的时候,对已经声明的变量或函数不再进行声明。
比如说
fn();//222 function fn(){ console.log('111'); } fn();//222 function fn(){ console.log('222'); } fn();//222 var fn='333'; fn();//会报错,开始的时候函数fn已经声明和定义 在var fn将不再声明 只会进行定义(赋值)333()肯定不是一个函数
再讲讲闭包吧
一般用到闭包就是保护变量的私有性,防止变量的污染。
(function(){ var num=22; return function(){ num++; console.log(num); } })()();//23
在js当中,作用域存在栈内存,而代码存在堆内存中,而堆内存如果有变量在占着就不会销毁,而如果堆内存当中没有引用就会自动销毁掉
而闭包中,就是利用到私有作用域,而这个作用域将不会销毁掉。起到一个保护私有变量的作用,但同时将占用内存。
就这些吧。下次将讲一下面对对象的一些特性,如原型,原型链什么的。