普通函数和箭头函数this的区别

普通函数的this指向跟函数的调用有关
  • 主动调用:

    • 函数名() ===> this指向window
  • 事件驱动调用:

    • ele.on + 事件类型 = 函数名 ====>this指向ele元素

    this是函数中的一个关键字,只有函数才有的一个关键字,谁调用这个函数,那么函数的thi就指向谁

<input type="button" id="btn" value="点击">
    <script>
        
        function fun(){
            console.log(this);          
        }
        fun() //直接调用,this指向window
        btn.onclick = function () {
        //给btn这个元素绑定点击事件,一点击就会执行fun函数,也就是相当于btn来执行fun函数,
        //那么fun中this指向这个btn这个对象
            console.log(this); //指向btn
            
        }
        
        

再来看看另外一个小例子

 var x = 10;
       var obj = {
           x:20,
           say:function(){
               console.log(this.x);
               
           }
       }
       obj.say()//输出20

为什么这里会输出20,而不是10呢?因为obj调用了say方法的函数,所以this的指向是obj,所以在这里输出的值为20,正是应合了普通函数中的这句话:谁调用这个函数,那么函数的thi就指向谁

箭头函数中没有所谓的this指向(this本来就是一个关键字)
  • 这个this跟箭头函数在哪里调用没有关系,但是跟箭头函数定义在哪里有关系
  • 箭头函数中没有arguments这个关键字

来看这个例子

 let obj = {
          name:"aa",
          say:()=>{
              console.log(this);//定义所处的位置实在window这个位置的,所以这里的this指向window        
          }
      }
      console.log(obj.say());

然后我们在定义一个普通函数在obj对象里面

let obj = {
          name:"aa",
          say:()=>{
              console.log(this);//定义所处的位置实在window这个位置的,所以这里的this指向window        
          },
          go:function(){
              console.log(this);//这个this指向obj.因为这个go方法是由obj来调用的,所以this指向obj
              
          }
      }
      console.log(obj.say());
      console.log(obj.go());

如果把say方法的箭头函数放到go方法函数里面去,看看会怎么样

 let obj = {
            name: "aa",
            go: function () {
                console.log(this);
                let say = () => {
                    console.log(this);//此时这个say的this指向obj这个对象 
                }
                say();

            }
        }
        console.log(obj.go());

为什么这个say方法的箭头函数会指向obj,因为say在go方法的函数里面,此时的go是指向obj的,所以say会跟着指向obj

现在重新写一个函数

let fun = function () {
	console.log(this)
}
fun()

顾名思义,这里的this指向是指向window,如果定义一个obj的对象,要将this的指向obj,这时候就要强行改变this的指向

  • call() 直接执行函数
    • 语法:函数名.call() 可以有多个参数
    • 但是注意:第一个参数为this的指向,第二个以后的参数都是给原来的函数传递实参的
let obj = {
	name:"张三"
}
let fun = function (info) {
	console.log(this.name + info)//此时this指向obj这个对象,控制台打印 张三18
}
fun.call(obj,18)
  • apply() 直接执行函数
    • 语法:函数名.apply() 只有两个参数
    • 但是注意:第一个参数为this的指向,第二个参数为一个数组(其实原来函数的实参)
let obj = {
	name:"张三"
}
let fun = function (info) {
	console.log(this.name + info)//此时this指向obj这个对象,控制台打印 张三今年18
}
fun.apply(obj,['今年18'])

如果要在apply()函数传递多个参数

let obj = {
	name:"张三"
}
let fun = function (info) {
	console.log(this.name + info)//此时this指向obj这个对象,控制台打印 张三今年18
}
fun.apply(obj,['今年18','好年轻呀'])
//此时控制还是打印 张三今年18

所以我们可以利用扩展运算符将对应传递的实参展开

let obj = {
	name:"张三"
}
let fun = function (...info) {
	console.log(this.name + info)//此时this指向obj这个对象
}
fun.apply(obj,['今年18','好年轻呀'])
//此时控制还是打印 张三今年18,好年轻呀
  • bind() 不直接执行函数
    • 语法:函数名.bind()
    • 返回值:一个新函数(跟原函数一模一样,只不过新函数这个this指向改变了)
    • bind的参数只有一个,这个参数为this的指向
    • 原函数的实参给bind函数的返回值添加
let obj = {
	name:"张三"
}
let fun = function (...info) {
	console.log(this.name + info)//此时this指向obj这个对象
}
var res = fun.bind(obj)
res('aa')

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值