默认全局变量为 window

优先级:new>显示绑定>隐式绑定>默认绑定

概要

  1. function函数this绑定规则
  2. 构造函数return this 之外的东西,生成的对象和this指向的情况
  3. 箭头函数this指向
  4. 例题

function函数

  1. 默认绑定

    独立调用,指向window

    console.log(this===window)   //true
  2. 隐式绑定

    谁调用就指向谁

    函数执行才会有this,每个函数都有自己的this,this指向是否相等由函数执行方式决定

    let obj = {
        foo : function(){
            console.log(this);  //obj
    
            function test(){
                console.log(this);
            }
            test()      //独立调用 指向window
    
            (function(){
                console.log(this);  //同上  window
            })();
    
            function back(){
                console.log(this);
            }
            return back;
        }
    }
    
    let a = obj.foo()  // obj window window
    a(); //window  独立调用
    // 变量赋值
    function foo(){
        console.log(this);
    }
    let obj = {
        foo : foo
    }
    
    obj.foo(); //obj
    
    let a = obj.foo; //隐式丢失 
    a(); // window
    // 参数赋值
    // 预编译过程中,实参被赋值为形参,值的浅拷贝的过程
    function foo(){
        console.log(this);
    }
    function bar(fn){   
        fn();
        new fn;  // foo {}
    }
    let obj = {
        foo : foo
    }
    bar(obj.foo);   //window
    // api 回调函数中的this 参考api文档
    
    let arr = [1,2,3];
    arr.forEach((item,idx,arr)=>{
        console.log(this)  //window
    });
    arr.forEach((item,idx,arr)=>{
        console.log(this)  //obj
    },obj);
  3. 显示绑定

    call,apply,bind

  4. new绑定

    指向实例化对象

    function obj(){
        let this = {};
        ....................
        return this;
    }

    如果构造函数return this之外的东西,生成的对象和this指向:

    function foo(){
        this.a = 2;
        console.log(this);   //{a:2}
        return {
            o : 0
        };
    }
    let f  = new foo;
    console.log(f);      // {O:0}
    function foo(){
        this.a = 2;
        console.log(this);   //{a:2}
        return 1;
    }
    let f  = new foo;
    console.log(f);     //{a:2}
    function foo(){
        this.a = 2;
        console.log(this);   //{a:2}
        return "asd";
    }
    let f  = new foo;
    console.log(f);    //{a:2}

箭头函数

本身没有this,不受绑定影响,this指向由外层函数作用域决定

function foo(){
    console.log(this);
    let test = ()=>{
        console.log(this);
    }
    return test;
} 
let obj1 = {
    foo : foo
}
let obj2 = {
    foo : ()=>{
        console.log(this);
    }
}
let o = obj1.foo();       // foo{}
let p = foo().call(obj);  // window
o();                      // foo{}   默认绑定无效
obj1.foo();               // window  隐式绑定无效
p();                      // window  显示绑定无效
let er = new foo();       // Error   箭头函数不允许作为构造函数

做做题把~~

function foo(s){
    this.a = s;
}
let obj = {};
let bar = foo.bind(obj);
bar(2);

console.log(obj.a);
let baz = new bar(3);
console.log(obj.a);
console.log(baz.a);

// 2 2 3
let name = 'window'
let obj1 = {
    name : '1',
    fn1 : function () {
        console.log(this.name);
    },
    fn2 : ()=> console.log(this.name),
    fn3 : function(){
        return function(){
            console.log(this.name);
        }
    },
    fn4 : function(){
        return ()=> console.log(this.name);
    }
}
let obj2 = {
    name : '2'
}


obj1.fn1();                    
obj1.fn1.call(obj2);

obj1.fn2();
obj1.fn2.call(obj2);

obj1.fn3()();
obj1.fn3().call(obj2);
obj1.fn3.call(obj2)();

obj1.fn4()();
obj1.fn4().call(obj2);
obj1.fn4.call(obj2)();


// 1
// 2

// window
// window

// window
// 2
// window


// 1
// 1
// 2