# 9.this

# 1 .函数内this的指向

这些this的指向,是当我们调用函数时确定的。

调用方式的不同决定了this的指向不同。

一边拿来说,指向调用者

调用方式 this指向
普通函数调用 window
构造函数调用 实例对象 原型对象里面的方法也指向实例对象
对象方法调用 该方法所属对象
事件绑定方法 绑定事件对象
定时器函数 window
立即执行函数 window

# 2 改变函数内部的this指向

JavaScript 中 提供了一些函数方法来处理函数内部this的指向问题,常用的有 bind()、call()、apply()三种方法

# call()方法

call()方法调用一个对象,一种调用函数的方式,同时可以改变this的指向。

fun.call(thisArg, arg1, arg2)

function test() {
    console.log(this)
}
function test2(){
    console.log(this)
}
test()
test.call(test2)
// call()用来ES6之前的继承
function Person(name, age) {
    this.name = name
    this.age = age
}
function Student(name,age,subject) {
    Person.call(Student,name,age)
    this.subject = subject
}

# apply() 方法

fun.apply(thisArg, [argsArray])
// thisArg: 在fun函数执行时,指定的this值
// argsArray: 传递的值,必须包含在数组里面
// 返回值就是函数的返回值,因为它就是调用函数

function test() {
    console.log(this)
}
function test2() {
    console.log(this)
}
test()
test.apply(test2)
function test3(color) {
    console.log(color)	// 'red'
    console.log(this)
}
test3.apply(test, ['red'])

// apply 主要应用:利用apply借助数学内置对象求最大值
let arr = [1,2,4,6,7,123,123]
console.log(Math.max.apply(Math, arr))
console.log(Math.min.apply(Math, arr))

# bind() 方法

bind() 不会调用函数,但是能够改变函数内部的this指向

fun.bind(thisArg, arg1, arg2,...)
// thisArg: 在fun函数执行时的this值
// arg1,arg2:传递的其他参数
// 返回由指定this值和初始化参数改造的原函数拷贝
function test (name, age) {
	console.log('我是'+ name + "今年" + age + '岁')
	console.log(this)
}
let person = {
	name: '张三',
    age: 18
}
let test2 = test.bind(person)
// 不会执行,返回的是函数拷贝
// 所以需要声明一个新的函数
test2('张三', 18)

// bind()也可以直接绑定参数
let test3 = test.bind(person, person.name, person.age)
test3()


// 不想函数立即执行,但是需要改变这个函数的this指向,使用bind
// 比如:有一个按钮,点击之后禁用该按钮,三秒之后再开启

let btn = document.querySelector('button')
btn.onclick = function () {
    this.disabled = true
    setTimeout(function () {
        // 定时器内部的this,是window
        // 所以不能 this.disabled = false
        // 在外部声明that = this,需要开辟内存空间
        this.disabled = false
    }.bind(this), 3000)
}

# 三个方法总结

相同点:都可以改变函数内部得this指向

区别点

  1. call和apply会调用函数,并且改变函数内部this指向
  2. call和apply传递的参数不一样,call 传递参数 arg1,arg2 , apply 以数组形式传递
  3. bind 不会调用函数,返回的是原函数拷贝

使用场景

  1. call用于继承
  2. apply 与数组有关系,比如借助Math对象计算数组最大、小值
  3. bind 不调用函数,但想要改变this指向,比如定时器内部的this指向
更新时间: 7/5/2021, 9:09:56 PM