this

141 阅读2分钟

一、初识 this

1.1 在Javascript中,this总是与函数(function)或对象的方法(method)密切关联着。this关键字可以帮助function和method“得到一个对象”,进而去使用这个对象。
let user = {
    name: 'duola',
    age: 18,
    sayHello () {
        console.log('hello!',this.name)
    }
}
// 利用this得到了user对象,并成功使用了user的name属性。
user.sayHello() // hello! duola
1.2 对于上例的补充
let user = {
    name: 'duola',
    age: 18,
    sayHello () {
        // 不使用this
        console.log('hello!',user.name)
    }
}
// 既然不用this也可以访问user对象,用了this是不是多此一举?
user.sayHello() // hello! duola
我们稍作改动
let user = {
    name: 'duola',
    age: 18,
    sayHello () {
        console.log('hello!',user.name)
    }
}
// 让admin指向user对象
let admin = user
// 让user指向null
user = null
admin.sayHello() // 报错信息:Cannot read property 'name' of null

二、正式介绍this

2.1 函数和方法中的this的本质是:当前的上下文环境。该上下文环境只有在函数被调用的那一刻才可以确定。
let user = { name: "duola" }
let admin = { name: "Admin" }
function sayHi () {
  console.log( this.name )
}
user.sayHello = sayHi
admin.sayHello = sayHi

user.sayHello() // (this === user)
admin.sayHello()//  (this === admin)
2.2 如何确定this的指向——请先找到函数或方法的调用位置,然后使用以下4项原则
2.2.1 默认绑定:可以把这条规则看作是无法应用其他规则是的默认规则
  • 默认规则的内容是:在函数或方法被单独调用的时候,严格模式下的this指向undefined,非严格模式的this指向window对象。
  • 注意:对于默认绑定来说,决定this绑定对象的并不是调用位置是否处于严格模式,而是函数体是否处于严格模式。
'use strict'
console.log(this) //window
function foo () {
  console.log(this) // undefined:处于严格模式的函数体的this指向undefined
  return function () {
    console.log(this) // undefined:处于严格模式的函数体的this指向undefined
  }
}
let bar = foo()
bar()
2.2.2 隐式绑定:点操作符
let user = {
    name: 'duola',
    sayHello: sayHi
}
function sayHi () {
    console.log(this.name)
}
user.sayHi() // duola 在初识部分已经讲过,不赘述
  • 注意:隐式调用会发生丢失this,如以下代码
let user = {
    nickname: 'duola',
    sayHello: sayHi
}
function sayHi () {
    console.log(this.name)
}
let sayHey = user.sayHello
sayHey() // undefined,因为此时的this已经是window
  • 为什么this丢失了?当我们写下let sayHey = user.sayHello发生了什么?为了不把这个文章写的太长,会在第2篇去写。
2.2.3 显示绑定
  • JS提供的绝大部分函数以及我们自己创建的所有函数都可以使用call(...)apply(...)方法来指定this的指向。
  • 这两个方法接收两个参数,第一个参数是一个对象,它们会将则个对象绑定到this,接着在调用函数时指定这个this。
  • 另外bind()也可以实现显示绑定
'use strict'
console.log(this) //window
function foo () {
  console.log(this) // undefined
  return function () {
    console.log(this) // 被bind绑定到了window
  }
}
let bar = foo().bind(this)
bar()
2.2.4 new绑定
  • this指向构造函数的实例对象
2.3 优先级
  • new > 显示绑定 > 隐式绑定 > 默认绑定