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

一、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(伪数组对象)
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值