javascript中this的指向

21 阅读2分钟

前言

在学习javascript这一门面向对象的语言,总是搞不清this的指向问题,理解和应用this是十分重要的,所以在学习过程中,遇到以下几种指向,通过文章记录下来

1.作为对象方法调用,this指向该对象

const obj = {
  name: 'zero',
  sex: 'female',
  sayHello() {
    console.log(`我的名字是:${this.name}, 性别是: ${this.sex}`) // 我的名字是:zero,性别是:female
  }
}
obj.sayHello()

2.作为普通对象调用,this指向全局对象window

  • 非严格模式下
    function test() {
      console.log(this) // Window 指向全局作用域
    }
    test()
  • 严格模式下
'use strict'
function test() {
  console.log(this) // undefined
}
test()

JavaScript高级程序设计中:在严格模式下,未指定环境对象而调用函数,则this值不会转为window。除非明确把函数添加到某个对象或者调用appy()或call(),否则this值将是undefined

3.作为构造函数调用,this指向新创建的对象

function Person(name, sex){
  this.name = name
  this.sex = sex
}
const zero = new Person('zero', 'female')
console.log(zero) // {name: 'zero', sex: 'female'}

4.通过call, apply, bind改变this的指向

function foo(sex, hobby) {
  return `我叫${this.name},年龄是${this.age},性别为${sex},爱好是${hobby}`
}

const obj = {
  name: 'Tom',
  age: 20
}


foo.call(obj, 'female','唱歌')   // 我叫Tom,年龄是20,性别为female,爱好是唱歌'
foo.apply(obj, ['male', '打球']) // '我叫Tom,年龄是20,性别为male,爱好是打球'
foo.bind(obj, 'female', '睡觉')  // 返回一个新的函数

简单说一下三者之间的区别:

call和bind传递的参数是一样的,多个参数依次传进去

apply传递的参数是以数组的形式进行传递

bind不会立即执行,是返回一个新的函数

5.箭头函数中没有this

  • 指向箭头函数定义时所处的对象,而不是箭头函数使用时所在的对象,默认使用父级的this
function foo() {
  var count = 1
  setTimeout(()=> {
    console.log(this.count) // 0
  }, 1000)
}
var count = 0
foo()

总结

  • 作为对象方法调用:函数作为对象的方法被调用,this指向该对象
  • 作为函数调用:函数直接被调用,this指向全局对象window
  • 作为构造函数调用:函数被new操作符调用,this指向新创建的对象
  • 通过apply或call或bind方法调用:this被显式地指定为调用apply或call或bind的第一个参数
  • 箭头函数中的this通常指向父级