2、预解释(变量提声)
一、为什么要学习预解释
1.带var和不带var的区别
2.明白obj[i]的i会报错
3.带var和不带var程序都能正常执行
4.规范代码,明白报错原因
二、认识预解释
1.浏览器自带机制
2.当浏览器加载html时,首先会提供一个供全局js执行的环境--全局作用域(window)。
三、预解释原理
在当前作用域下,js代码执行之前,浏览器会对带var和function的进行提前声明或定义。
1.声明(declare)--告诉浏览器在当前作用域下有这个东西了
定义(defined)--给函数fun定义
2.对于带var和带function的预解释机制是不一样的:
带var的知识提前声明不定义,默认值是undefined
带function的声明加定义都完成。
3.预解释只发生在当前作用域中,最开始只对window下进行预解释,若在某个函数里面带var和带fun的,只有当函数执行的时候,才会与解释。
四、全局作用域中带var和不带var的区别:
1、带var的会进行预解释,放在赋值前面为undefined,,不带var的不能被预解释,放在赋值前面会报错
2、不带var的相当于给window增加了一个属性 和属性值;(window.num)带var的不仅是全局变量,也相当于给window增加了一个属性和属性
3、如果私有域中出现的变量不是私有变量,则往当前作用域的上一级作用域查找,如果上级也没有继续查找,一直找到window为止。
如果window下也没有,则分两种情况处理:
1)获取值:console.log() 会报错。
2)设置值:也相当于给window增加了一个属性和属性值。
五、预解释机制的无节操
1、关键字in:"num" in window;判断num是否为window的一个属性,是返回true,不是返回false
2、预解释的时候,遇到判断句,不管条件是否成立,都要把带var的进行提前的声明。
3、只对等号左边进行预解释;
var fn=function (){}; 属于匿名函数的函数表达式:把函数的定义部分当做一个值赋给变量或者元素的某一个事件。
函数表达式右边的是值,不是定义部分,不参与预解释。(此时函数的执行只能在定义的后面,否则会报错-->undefined() is not a function)
4、自执行函数:定义和执行一起完成;自执行函数的定义部分在全局作用下不进行预解释,当代码加载到这里的时候,定义和执行一起 完成了。
5、函数体中return 下面 的代码虽然不执行,但是需要进行预解释,但是return 后面紧跟 的是函数要返回的值,所以不进行预解释。
6、在js中,如果变量的名字和函数的名字重复,也算冲突,(预解释的时候声明了两次)
7、在预解释的时候,如果如果一个属性名已经声明过了,不需要重新声明(只声明一次,后面不会重新声明),但是需要重新定义(函数)或赋值(变量)。
(变量不需要重新定义,但是会重新赋值,函数不需要再声明但是会重新定义)
/* var n=9; var s="str"; function fn(){ alert(n); alert(s); n=7; var n=6; alert(n); } fn();*/ /* var oBtn=document.getElementsByTagName("input"); for(var i=0;i<oBtn.length;i++){ oBtn[i].onclick=function(){ for(var j=0;j<oBtn.length;j++) { oBtn[j].style.background="red"; } } } */ /* alert(a); var a=3; // alert(a); function fn(a){ alert(a); a=1; alert(a); } // m=1; // alert(m) fn(); fn(a)*/ /*f=function(){return true}; g=function(){return false}; (function(){ if(g()&&[]==![]){//会对函数g进行预解释,所以函数内g() 函数执行会返回结果true; f=function(){return false}; function g(){return true}; } })(); console.log(f()); console.log(g());*/ // ???????对函数g()进行预解释后,函数执行放在函数定义前面也会执行。 /* var name="dalyn"; var age="500"; name=(function(name,age){ name="DALYN" ; age= age||this.age; console.log(name,age) })(name) console.log(name,age) //函数没有返回值 所以是undefined */ // 注意运算符的优先级 /*var i=3; function fn(){ i*2; return function(n){ console.log(n*(++i)) } } var f=fn(); f(3); fn()(3); f(4); fn()(4);*/ function fn(){ var i=10; return function(n){ console.log(n+(++i)) } } var f=fn(); f(15); f(20);//不销毁 函数中return的返回值被变量f占据 之后后面小函数执行完毕销毁 fn()(15);//不立即销毁 函数中return的返回值被变量f临时占据,(15)执行完毕后都销毁了。 fn()(20); fn()(30); f(30);