预解释

预解释

为何学习预解释:

  1. 报错的时候,为何会报错?
  2. 带var和不带var的区别?
  3. 代码应该写在什么地方?
  4. 当代码不一样的时候,弹出同样的i,结果却不同?

    undefined

  5. obj.xxx–>xxx属性下的值不存在的时候
  6. function的没有返回值的时候;
  7. 定义形参执行的时候没有传
  8. 在预解释的时刻,var声明的变量在赋值之前是undefined;

    全局变量和私有变量

  • 定义在script里的变量就是全局变量;定义在函数里的就是私有变量
  • 在函数外不可以读取函数内定义的私有变量,在函数内部是可以读取全局变量甚至修改
  • 尽量不要往全局变量存值

    全局作用域和私有作用域

  • 函数执行的时候形成一个私有作用域,
  • 全局作用域只要打开浏览器就已经产生,一般用window表示

    声明和定义

  • 概念:在当前作用域下,在JS代码执行之前,浏览器会对带var和带function的进行声明或定义;
  • 带var的:只声明不定义; var abc;
  • 带function声明过的函数:声明加定义
  • 如果函数名字和变量名字重名,在预解释阶段以最后一个函数为准,当代码执行到变量赋值的那一行,以这个变量为准

    关于函数

  • 函数定义三阶段:
    1. 开辟一个空间地址
    2. 把函数体中的所有JS代码作为字符串放在这个空间中
    3. 把空间地址赋值给函数名
  • 函数执行四阶段:

    1. 形成一个私有作用域
    2. 形参赋值
    3. 预解释:
    4. 代码从上到下的执行;
      1
      2
      3
      4
      5
      6
      7
      var n=123;
      function fn(){
      alert(n)
      n=456;
      alert(n)
      }
      fn(4);
  • 以上题涉及到的新知识点:

    1. 作用域链:当函数被调用的时候,形成一个私有作用域;我们找私有变量n;
      如果有私有变量n,那么整个函数中的n都是该函数的私有变量,跟外界没有任何关系;
      如果没有私有变量n,就到该函数的上级作用域进行查找,找不到,继续往上找,一直找到window,还没有的话:报错!
    2. 带var 和不带var 的区别:
      • 带var会进行预解释;在全局作用域下,他也是window的全局属性;
      • 不带var不会进行预解释;如果进行赋值的话,就是给window进行全局属性的赋值;window.xxx=xx;
    3. 私有变量有2种:1)形参 2)函数中带var的;
    4. 上级作用域:跟函数在哪里调用无关;只跟函数对应的堆内存在哪里开辟有关;

      内存和内存释放

  • 栈内存:形成一个供JS代码执行的环境:1)全局作用域 2)私有作用域

    • 全局作用域:当浏览器加载完页面的时候,全局作用域就形成了
      • 销毁:关闭页面
    • 私有作用域:一般当函数执行完成的时候,自己就销毁,有两种情况不销毁:

      • 不销毁:当函数里面的东西,被外面的变量或其他东西占用的时候,就不会销毁了

        • return被占用:当函数执行完成的时候,会返回一个引用数据类型的值,这个值销毁,所有的函数才能销毁;fn()();
        • 函数内的引用数据类型被同时赋予给函数外的变量;(如果不return出来,那么可以到函数里去占用它)
        • 在绑定时间的时候,也有可能和作用域不是释放掺和在一起
          1
          2
          3
          4
          5
          6
          Element.onlick= (function(){
          var count = 0;
          return function fn(){
          console.log(++count);
          }
          }())
      • 自执行函数也不不立即销毁:

  • 堆内存:他用来存放数据的;
    • 对象数据类型:存的是键值对
    • 函数数据类型:存的是代码字符串;
    • 堆内存的销毁:var obj={} var fn=xxxff00; 销毁方式=》obj=null; fn=null;

      预解释无节操:

  1. 只对等号左边带var,声明不定义
  2. 自执行函数不会进行预解释,只有执行到他的时候,声明+定义+调用同步完成
  3. 条件判断语句中无论条件是否成立都会进行预解释;–提醒我们:不要在条件判断语句中写函数的定义阶段
  4. return后面的语句不会进行预解释,return下面的语句虽然不执行,但会进行预解释
  5. 已经声明过的变量不会进行重复声明;

    运算符的优先级:算术》比较》逻辑》赋值 ; 所以一般用到赋值运算符的时候,都要加()提高优先级;

    ++i 先++,后运算; i++ 先运算再++; ++i也有强制转化为数字的默认行为

函数执行的过程

  1. 只要函数执行就需要浏览器提供一个私有作用域
  2. 形参赋值:形参相当于定义在当前函数体内的私有变量
  3. 先预解释当前函数体内带var和function的
  4. 代码从上往下执行