this的学习

59 阅读2分钟

// this是动态的,随着触发函数的对象而改变

    //  1.全局作用域中的this 指向的是window

    // 函数中的this,指向的一定是对象
    //  函数方法体内的this,谁调用指向谁
    var obj = {
        fun:function(){
            console.log('this',this);
        }
    }
    obj.fun(); // 指向对象
    var fun = obj.fun;
    fun();//  指向window
    
    
    
    
    
 this判断方式
    var a = this.name;
    var obj = {
        foo:function(){
            console.log(this);
        }
    }
    //   this 判断规律  第一看 [在哪里]
    //   全局  this ===window
    //   箭头函数中,没有this  使用上一层作用域中this
    //   function 函数方法体中
    //    第二看 谁触发的函数  this  就指向谁

    //    1.new  触发的函数  this===实例化的对象
    //    2.call apply bind 触发的函数  this === 参数1 赋值的对象
    //    3.普通对象触发的函数,谁调用指向谁  this=== 函数旁边的对象
    
    
    
  函数里的this
  var obj = {
        foo:function(){
            console.log('函数1 thos',this);
        },
        xieke:{
            // bar:obj.foo,   bug还没赋值就使用了
            fun:function(){
                console.log('fun中this',this);
            }
        }
    }
    //  分析每一个属性存值的特点

    //  判断this 指向
    //   第一步 执行的是哪一个元素
    //    第二部 看谁触发的函数
    obj.foo();    //  指向obj对象   触发函数1
    var a =obj.foo;
    a();    //   指向window  触发函数1
    var obj2 = {}
    obj2.foo = obj.foo;
    obj2.foo()   //  指向obj2对象   触发函数1
    
    
 空值的出现
    function foo() {
        //函数1
        console.log(this.name);
    }
    var obj = {
        name: 'nihao',
        foo: function () {
            // 函数2
            console.log(this.name);
        }
    }
    var obj1 = {
        name: 'wohao'
    }
    var obj2 = {
        name: 'dajiahao'
    }
    foo();          // 1:执行函数   2:this 在function 中   3:window.foo() --->this === window   window.name === ""
    obj.foo();      // 2:执行函数2    2:this 在function 2中   3:obj.foo()  --->this === obj  obj.name === 'nihao'                       
    foo.call(obj)   // 3:执行函数1    2:this在function 2中    3:obj.foo() ---> this === obj  obj.name === 'nihao'
    foo.apply(obj1) // 4:执行函数1     2:this 在 function foo中  3:obj1 ---> this === obj1  obj1.name === 'wohao'
    foo.bind(obj2)() // 5:执行函数1   2:this 在 function foo中  3:obj2 ---> this === obj2   obj2.name === 'dajaihao'
    obj.foo.apply(obj2); // 6:执行函数2   2:this在函数2中   3:obj2 ---> this === obj2    obj2.name === 'dajiahao'

    var a = new obj.foo(); 
    // 1:执行函数2
    // 2:this 在 function 中
    // 3:new 触发 this === a --> this.name == a.name
    // undefined

    var res = obj.foo.bind(obj2)
    res()
    // 1:执行函数2
    // 2:this 在 function 中
    // 3:bind 的触发函数 this === obj2 --->this.name ===obj2.name
    // 'dajiahao'
    var res1 = obj.foo;
    res1()
    // 1:执行函数2
    // 2:this 在 function 中
    // 3:window.res1()
    // this === window
    // window.name === ""
    
    
 下面关于一些特殊的this,
 构造函数中的this
 function son(name,age,dec){
        this.name = name;
        this.age = age;
        this.dec = dec;
        //  注意构造函数不能有return
    }
    var luotao = new son('罗涛',18,'呆');
    //  new 触发 函数
    //  this 指向 new 实例化的对象  luotao
    console.log(luotao);
    
    
    bind/call/apply/箭头函数
  //  箭头函数没有this,和arguments
    //  所以箭头函数中this ,使用的是上一层作用域中的this
    // var foo = () => {
    //     console.log(this, "函数1");
    // }
    // var obj = {
    //     foo: foo
    // }
    // obj.foo()  //  上一层作用域是全局作用域,所有this为window


    const obj = {};
    function test(a,b) {
        console.log(this);
        console.log(a,b);
        console.log(obj === this);
    }
    const testObj = test.bind(obj);
    //  bind函数可以更改this指向,改为括号里的内容
    test();
    testObj();//this指向obj

    test.apply(window,[1,2])
    //  和bind类似
    // apply()触发函数,改变函数中this指向,
    //  参数1  this 指向的对象
    //  参数2   数组 给触发函数传入实参
    // test.call(window,2,3)
    // 触发函数,改变函数中this指向
    //  参数1   this指向的对象
    //  参...   执行函数时传入的实参