JS中this的指向与改变this指向的三个方法

目录

一、this指向的分类

1、全局函数的调用

2、对象中函数的调用

3、setTimeout与setInterval中的this

4、事件绑定中的this

5、箭头函数中的this

6、构造函数中的this

二、改变this指向的三个方法

1、临时改变this,且立即执行

2、永久改变this,不会立即执行

三、call、apply和bind的使用场景


一、this指向的分类

        this的指向基本遵循一句话:谁调用这个函数,函数里的this就指向谁

1、全局函数的调用

        如果是调用全局函数,那么函数中的this指向的就是window对象

function f1(){
    console.log(this) // window
}
f1()

        因为我们定义的全局函数或者是全局变量都是挂载在window身上的,所以全局函数的调用就相当于:window.函数名()

2、对象中函数的调用

        在调用一个对象中的函数时,由于是通过对象调用,所以函数中的this指向的是该对象

var obj={
    a:1,
    b:function(){
        console.log(this)
    }
}
obj.b()//obj这个对象

3、setTimeout与setInterval中的this

        setTimeout和setInterval中使用this指向的是window。因为函数是以回调函数的形式存在的,回调函数被window所调用。

setTimeout(function(){
    console.log(this)//window对象
},1000)

setInterval(function(){
    console.log(this) //windowd对象
},200)

4、事件绑定中的this

        事件绑定中的this指向,即该事件绑定在谁身上,this指向的就是哪个节点,继而可以通过this操作节点的样式、内容等。

<body>
    <button id="btn">点我</button>
    <script>
        btn.onclick=function(){
            console.log(this)  //<button id="btn">点我</button>
        }
    </script>
</body>

5、箭头函数中的this

        如果在箭头函数中使用this,该this的指向是上一级非箭头函数的this指向,或者说是父级对象的this指向

btn.onclick=function(){
    inp.onfocus=()=>{
        console.log(this) //当输入框获取到焦点时,this指向的是btn
    }
}

6、构造函数中的this

        不论是前辈们定义好的,还是自定义构造函数,其中的this指向的都是当前的实例化对象

function CreateObj(){
    this.a="1",
    this.b:function(){
        console.log(this) //指向的是当前的实例化对象
    }
}

var c1=new CreateObj()

c1.b() //指向的是c1


var c2=new CreateObj()

c2.b() //指向的是c2

二、改变this指向的三个方法

        在JS中,有三个方法可以改变this的指向:call、apply和bind

        语法:

                需要借用this的对象.call/apply/bind(借给别人this的对象,传参)

1、临时改变this,且立即执行

        其中的call和apply都只是临时的借用某个对象的this,并且会自动的执行当前的函数。

function calc() {
    return this.name + "你好";
}

var nn = { name: "张三" };

// 这句话的意思是:将nn对象的this临时借给calc函数
var res=calc.call(nn);
//var res=calc.apply(nn);

console.log(res) //"张三你好"

        上述例子使用apply和call的结果都相同,那么它们之间的区别是什么?

        call和apply在传参时有不同

  • call在传参时要求传入函数的实参必须单独传入,例如:xxx.call(yyy,参数1,参数2...);
  • apply在传参时要求传入函数的实参必须是一个数组,如:xxx.apply(yyy,数组对象)。但是在apply内部会把这个数组拆分开;

2、永久改变this,不会立即执行

        剩余的bind方法作用就是永久的将某个对象中的this改变为另一个对象的this,改变之后原本的函数不会立即执行,需要手动的调用

        使用bind改变this总共做了三件事:

                 1)、创建了—个和原函数功能完全一样的新函数

                2)、将新函数中的this永久绑定为你指定的对象;

                3)、将新函数中的部分参数永久固定

function f1(){
    return this.a
}

var obj={
    a:123
}

var newF1=f1.bind(obj) //将f1的this永久改变为obj的this

console.log(newF1())  //123

注意:bind绑定在新函数中的this,无法被call、apply再次被借走。

function f1(){
    return this.a
}

var obj={
    a:123
}

var newF1=f1.bind(obj) //将f1的this永久改变为obj的this

console.log(newF1())  //123

function f2(){
    console.log(this)
}


f2.call(newF1)  //此时打印的是f1的内容,而不是newF1的内容

三、call、apply和bind的使用场景

        1、比较出数组中的最大值和最小值:Math.max/min.apply(Math,arr)

        2、得到Object最原始的toString: Object.prototype.toString.call/apply(arr);

        3、将类数组对象转为普通数组: var新数组=Array.prototype.slice.call/apply(伪数组对象)

猜你喜欢

转载自blog.csdn.net/txl2498459886/article/details/126804412
今日推荐