this指向:this绑定规则 + 箭头函数

目录

一、this绑定规则

二、this指向

三、额外函数补充:apply、call、bind

1.apply和call

2.bind

四、this绑定规则优先级

五、this规则之外

1、忽略显式绑定

2、间接函数引用

六、箭头函数

1、箭头函数的缩写

2、箭头函数中this使用

3、箭头函数中this应用


一、this绑定规则

  • 默认绑定:非严格模式下this指向全局对象,严格模式下。独立调用的函数中的this指向的就是undefined
  • 隐式绑定:当函数引用有上下文对象时,如 obj.foo() 的调用方式,foo 内的this指向 obj (采取就近原则)
  • 显式绑定:通过 call() 或者 apply() 方法直接指定this的绑定对象,如 foo.call(obj)
  • new绑定:使用new来调用一个函数,会构造一个新对象并把这个新对象绑定到调用函数中的this

🏷️new绑定:

  1. 创建新的空对象
  2. 将this指向这个空对象
  3. 执行函数中的代码
  4. 没有显示返回非空对象时,默认返回这个对象

二、this指向

根据函数的调用方式的不同,this会指向不同的对象:

  • 以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this的指向永远都是window。比如fun();相当于window.fun();
  • 以方法的形式调用时,this指向调用方法的那个对象
  • 以构造函数的形式调用时,this指向实例对象
  • 以事件绑定函数的形式调用时,this指向绑定事件的对象
  • 使用call和apply调用时,this指向指定的那个对象

三、额外函数补充:apply、call、bind

1.apply和call

function foo(name, age, height) {
  console.log("foo函数被调用", this)
  console.log("参数", name, age, height)
}
  foo("xxiaoming", 18, 120)
  foo.apply("apply", ['xiaohong', 20, 150])
  foo.call('call', 'xioalan', 17, 180)

apply调用:第一个参数:绑定this

                    第二个参数:传入额外的参数,以数组的形式

call调用:第一个参数:绑定this

                 第二个参数:参数列表,后续的参数以多参数的形式传递

2.bind

    function foo(name, age, height) {
      console.log("foo函数被调用", this)
      console.log("参数", name, age, height)
    }
    var obj = {name: 'xiaoming'}
    
    // 需求:调用foo函数时,总是绑定到obj对象身上(不希望obj对象身上有函数)
    var bar = foo.bind(obj)
    bar()     // this  -> obj

call与apply在改变this指向的同时就会立即执行函数,而bind绑定this后不会立马执行,而是返回一个新的绑定函数。

除此之外,bind属于硬绑定,即this指向与传进去的形参在bind方法执行的时候就已经确定了,无法再次改变,再运行这个函数,就相当于无参。

四、this绑定规则优先级

📝 显式绑定 > 隐式绑定 > 默认绑定

      new绑定 > 隐式绑定 > 默认绑定

📝new绑定与显式绑定:

  • new绑定不可以和 apply / call 一起使用,所以不存在谁的优先级更高
  • new绑定优先级高于 bind
  • 显式绑定中,bind 优先级高于apply / call

五、this规则之外

1、忽略显式绑定

apply / call / bind:当传入null / undefined 时,那么使用的规则是默认绑定,自动将this绑定程全局对象

2、间接函数引用

隐式绑定 谁调用,this就是谁

返回值是目标函数的引用

六、箭头函数

箭头函数允许我们用更短的语法定义函数。

箭头函数可用于替代传统函数function() { }

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。

箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

1、箭头函数的缩写

1.如果箭头函数只有一个参数,那么 ()可以省略

names.forEach(item => { console.log(item) })

2.如果函数体中只有一行代码,那么大括号{ } 可以省略

names.forEach(item => console.log(item))

3.只有一行代码时,这行代码的表达式结果会作为函数的返回值返回的。

   一行代码中,不能带return关键字,如果省略,需要带return一起省略

var newNums = nums.filter(item => item % 2 === 0)

4.如果默认返回值是一个对象,那么这个对象必须加 ( )

var bar = () => ({name: "haha", age: 17})

2、箭头函数中this使用

普通函数中是有this的标识符,而箭头函数中,压根没有this。通过apply调用时,也是没有this的

3、箭头函数中this应用

var obj = {
  data: [],
  getData: function() {
    setTimeout(function() {
      var result = ["abc","cba","nba"]
      this.data = result
    },2000)
  }
}

obj.getData()
console.log(obj.data);//Array(0)
//此时obj拿不到result数组,
//因为this指向出了问题:setTimeout的this指向是window,此时obj的data仍是空数组

改进:

我们需要在外层定义:var _this = this

在setTimeout的回调函数中使用 _this 就代表了obj对象

var obj = {
  data: [],
  getData: function() {
    var _this = this
    setTimeout(function() {
      var result = ["abc","cba","nba"]
      _this.data = result
    },1000)
  }
}

obj.getData()
console.log(obj);

使用箭头函数:

var obj = {
  data: [],
  getData: function() {
    setTimeout(() => {
      var result = ["abc","cba","nba"];
      this.data = result;
    },1000)
  }
}

obj.getData();
console.log(obj);

 
/*data: Array(3)
0: "abc"
1: "cba"
2: "nba"
length: 3
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值