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);

 

posted @ 2017-08-01 13:29  dalyn  阅读(144)  评论(0编辑  收藏  举报