震惊!!!一眼就能看懂的this指向问题!!!!

  • this的显示绑定和隐式绑定
    显示绑定:当一个函数没有明确的调用对象时,单独作为独立函数调用,将对函数的this使用默认绑定,绑定到全局window对象
    例子一(函数内嵌套函数):
    var a = 1
    console.log(this.a) // 1,this指向window
    function god () {
    var a = 2;
    console.log(this.a) // 1,this指向window
    function myGod () {
    var a = 3;
    console.log(this.a) // 1,this指向window
    }
    myGod()
    console.log(this.a) // 2,this指向god
    }
    god()

    与作用域的区别:全局作用域和局部作用域,去掉this,都是从自身作用域查找变量,找不到从上层找
    var a = 1
    console.log(this.a) // 1,this指向window
    function god () {
        var a = 2;
        console.log(a) // 2,在god函数作用域
        function myGod () {
            var a = 3;
            console.log(a) // 3,在mygod函数作用域
        }
        myGod()
    }
    god()
    
     隐式绑定:当函数被一个对象“包含”的时候,this被隐式绑定到对象里面,this可以直接访问绑定对象里的其他对象
     例子2
    var god1 = {
        a: 1,
        mygod1: function () {
            console.log(this == god1) // true,god1中有fire函数,this指向obj
            console.log(this.a) // 1 this指向god1
        }
    }
    god1.mygod1()
    
    例子3(动态绑定:this是在代码运行期间进行的绑定过程)
    var god2 = {
        b:1,
        myGod2 : function () {
            console.log(this.b) // 1,this指向god2
        }
    }
    var b = 2;
    god2.myGod2()
    var ohmyGod2 = god2.myGod2
    ohmyGod2() // 2,ohmygod2是全局变量,this对于god2绑定丢失,默认绑定在全局window
    
    this指向:不是由谁定义this决定的,而是随脚本解析自动赋值
    (1)全局环境作用域:this全局环境始终指向window
    console.log(this === window) // true
    console.log(window.alert === this.alert) // true
    
    (2)函数环境作用域:函数由谁调用,this就指向谁
    this.b = "mm"
    console.log(b) // mm
    function fn() {
        console.log(this) // window
    }
    fn() === undefined // true
    
    (3)对象中的方法函数调用:指向该方法所属的对象
    var fn1 = {
        c:1,
        fnn1: function() {
            return this
        }
    }
    console.log(fn1.fnn1()) //c:1, fnn1:function(){},函数被fn1调用,this指向fn1
    var c = 3;
    var newfn1 = fn1.fnn1; // 此时更改this指向为全局变量newfn1
    newfn1() // 3,this指向全局变量newfn1,window中c为3
    

    (4)构造函数中,this始终指向新对象
    function fn2 (age, name) {
    this.age = age
    this.name = name
    console.log(this)
    }
    var f1 = new fn2(10, “张三”) // fn2 {age: 10, name: “张三”}
    var f2 = new fn2(12, “李四”) // fn2 {age: 12, name: “李四”}

    (5)通过事件绑定的方法,this指向绑定事件的对象
    

    (6)定时器函数,因为异步操作,this都指向window,可以通过bind改变this指向
    定时器嵌套
    function fn3() {
    this.age = 1;
    setTimeout(function () {
    console.log(this)
    },3000)
    }
    var p = new fn3(); // 3s后返回window对象,并没有age,this指向全局

    通过bind绑定改变this指向
    function fn4() {
    this.age = 1;
    setTimeout((function () {
    console.log(this)
    }).bind(this),3000)
    }
    var p = new fn4(); // 3s后返回fn4对象,this指向fn4

    (7)箭头函数:是ES6新增的一种新的函数,比普通函数表达式更为简洁。
    箭头函数与普通函数的区别:
    this指向:箭头函数没有prototype原型,本身没有this属性属性;箭头函数中this指向作用域链上最近的一个this,跟使用位置无关;如果箭头函数外层没有普通函数,this就会指向全局;
    在箭头函数中不能直接改变其this指向,只能去修改普通函数的this指向,箭头函数中才会跟着修改。
    箭头函数不能作用构造函数,不能使用new,会直接报错;
    箭头函数不能使用arguments对象,该对象在函数体内不存在,如果要用可以用rest代替
    因为箭头函数本身没有this,所以也不能调用call,apply,bind属性

    (8)更改this指向,通过call(),bind(),apply
    call()和apply()在特定作用域调用函数, bind()会创建一个函数的实例,this会被绑定到bind函数
    call()
    var fn4 = {
        name: "张三",
        age:10
    }
    function fnn4(x,y) {
        console.log(x+','+y)
        console.log(this)
        console.log(this.name)
    }
    fnn4(3,4) // 3,4 window 空,其中this指向window
    fnn4.call(fn4,3,4)// 3,4, fn4{}对象, "张三"
    
    apply(),不同在于提供参数的方法,apply提供参数数组,而不是参数列表
    fnn4.apply(fn4,[3,4])// 3,4, fn4{}对象, "张三"
    
    bind(),是创建一个新的函数,当目标函数被调用时this的值绑定到bind()的第一个参数上
    fnn4.bind(fn4,3,4) // 只是更改了this指向,没有输出
    fnn4.bind(fn4,3,4)() // 3,4, fn4{}对象,"张三"
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值