javascript this指向

this不是指自身,它是一个指针,指向调用函数的对象。

1.默认绑定

默认绑定,在不能应用绑定规则时使用的默认规则,通常是独立函数调用。

function sayHi(){
    console.log("My name is "+ this.name)
}
var name = 'Li Lei'
sayHi()  // My name is  Li Lei

在调用sayHi()时,使用了默认绑定,this指向全局对象(非严格模式),如果是严格模式(“use strict”),this指向undefined,undefined上没有this对象,会抛出错误
在这里插入图片描述

2.隐式绑定

函数的调用是在某个对象上触发的,即调用位置上存在上下文对象。典型的形式是XX.fun()。我们来看一段代码:

function sayHi(){
    console.log("My name is "+ this.name)
}
var person = {
    name: 'Li Yang',
    sayHi:sayHi,
}
var name = 'Li Lei'
person.sayHi()  // My name is Li Yang

sayHi函数声明在外部,严格来说并不属于person,但是在调用sayHi时,调用位置会使用person的上下文来引用函数,隐式绑定会把函数调用中的this(即此例sayHi函数中的this)绑定到这个上下文对象(即此例中的person)
注意:对象属性链中只有最后一层会影响到调用位置。
隐式调用丢失:
a.如果链式用本地的一个变量接受,就要看改变量的上下文。如下:

function sayHi(){
    console.log("My name is "+ this.name)
}
var person = {
    name: 'Li Yang',
    sayHi:sayHi,
}
var name = 'Li Lei'
var Hi = person.sayHi
Hi()  // My name is Li Lei

b.回调函数

        function sayHi(){
            console.log("Hello",this.name)
        }
        var person1 = {
            name:"Li Yang",
            sayHi:function(){
                setTimeout(function(){
                    console.log("Hello",this.name)
                })
            }
        }
        var person2 = {
            name:"Li Mei",
            sayHi:sayHi,
        }
        var name = "Li Tao";
        person1.sayHi();
        setTimeout(person2.sayHi,100)
        setTimeout(function(){
            person2.sayHi()
        }, 200);
       // Hello , Li Tao
       // Hello , Li Tao
       // Hello , Li Mei

第一条,setTimeout的回调函数中,this使用的默认绑定,非严格模式下,执行的是全局对象
第二条,XX.fun()的时候,fun中的this指向的是XX,为什么不是这样?setTimeout(fn,delay){ fn(); },相当于是将person2.sayHi赋值给了一个变量,最后执行了变量,这个时候,sayHi中的this显然和person2就没有关系了。
第三条,虽然也是在setTimeout的回调中,但是我们可以看出,这是执行的是person2.sayHi()使用的是隐式绑定,因此这是this指向的是person2,跟当前的作用域没有任何关系。

3.显示绑定

显式绑定比较好理解,就是通过call,apply,bind的方式,显式的指定this所指向的对象。

        function sayHi(){
            console.log("Hello",this.name)
        }
        var person = {
            name:"Li Yang",
            sayHi:sayHi
        }
        var name = "Li Mei";
        var Hi = person.sayHi;
        Hi()
        Hi.call(person) //  Hi.apply(person)
			
		//	Hello Li Mei
		//  Hello Li Yang

使用硬绑定明确将this绑定在了person上

4.new绑定

使用new来调用函数,会自动执行下面的操作;
1.创建一个新对象;
2.将构造函数的作用域赋值给一个新对象,即this指向这个新对象;
3.执行构造函数中的代码;
4.返回新对象

        function sayHi(name){
            this.name = name ;
        }
        var Hi = new sayHi("Li Mei")
        console.log("Hello",Hi.name)

箭头函数

箭头函数是ES6中新增的,它和普通函数有一定区别,箭头函数没有自己的this,它的this继承于外层代码库的this
1.函数体内的this对象,继承的是外层代码块的this;
2.不可能当作构造函数,也就是说,不可以使用new命令;
3.不可以使用arguments对象,改对象在函数体内不存在。如果要用,可以用rest参数代替;
4.不可以使用yield,因此箭头函数体不能作用Generater函数;
5.箭头函数没有自己的this,所以不能使用call(),apply() 或bind()来改变this指向

        var obj = {
            hi:function(){
                console.log(this,"Hi");
                return ()=>{
                    console.log(this,"Hi=>()")
                }
            },
        }    
        let fun1 = obj.hi();
        fun1();
        // hi  
        // hi

猜你喜欢

转载自blog.csdn.net/weixin_44420276/article/details/88954534