JavaScript预解析和this指向

60 阅读2分钟

预解析

解析顺序

  1. 自身函数参数->函数申明->var变量->其他语句执行
  2. 注意只有var才有变量提升,ES6的let/const是没有的

举例

function a(){
    console.log(a);  // function
    function a(){};
    var a = 10;
    console.log(a); //10
}
a();
  • 具体执行过程为:
    1. 执行函数参数-->无函数参数
    2. 执行函数声明--> function a(){}
    3. 执行var 声明 --> var a;与函数声明重名,被忽略
    4. 执行其他语句: console.log(a) -->function, a = 10;
      console.log(a) --> 10;**

this指向

  1. window是js在浏览器中的全局对象,我们创建的变量实际上是给window添加属性

  2. this的指向原理

    • 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window
    • 如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
    • 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
  3. 举例

    const o = {
        a:10,
        b:{
            // a:12,
            fn:function(){
                console.log(this.a); //undefined
            }
        }
    }
    o.b.fn();
    
    • 尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。
    const o = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a); //undefined
                console.log(this); //window
            }
        }
    }
    const j = o.b.fn;
    j();
    
    • this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,上例中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和之前直接执行o.b,fn()是不一样的
  4. 在严格版中的默认的this不再是window,而是undefined

申明函数

  1. 在定义一个函数时,function F(){} js内部会执行2个动作

    1. 为该函数添加一个原型(prototype)属性
    2. 为prototype对象额外添加一个constructor属性并且该属性保存指向函数F的一个引用
  2. 对象实例内部都会自动保存一个指向其构造函数的prototype对象的一个属性__proto__