概念
每一个函数内部都有一个关键字this
this 的值, 只和函数的调用有关, 与函数书写无关
- 一个普通的全局函数, 在正常调用的情况下, this === window
- 如果将函数放置到对象, 通过对象的语法去获取到并调用, 那么 this === 对象
- 如果将函数作为 事件处理函数, 那么触发的时候, 内部的 this 指向了 事件源
- 如果将函数作为定时器执行时的函数, 那么触发的时候, 内部的 this 指向了 全局对象 window
<style>
#box {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
<div id="box"></div>
<script>
function fn() {
console.log(this) // 这一行不能决定 this 的值, 想要知道他的值是什么, 需要调用函数的时候才能确定
}
// 1. 普通调用方式
fn() // this === window
// 2. 将函数fn赋值给对象obj的c属性 fn 和 obj.c 是一个引用地址
var obj = {
a: 1,
b: '我是对象obj的属性B',
c: fn
}
obj.c() // this === obj this 指向了调用者,也就是对象
// 3. 事件的方式触发
var box = document.getElementById('box')
box.onclick = fn // this === box this 指向了事件源
// 4. 倒计时器
setTimeout(fn, 0) // this === window
setInterval(fn, 1000) // this === window
</script>
改变this的指向
需求
让这个函数在不改变结构的情况下, 让其内部的 this === obj
1.call()
语法 : 函数.call(this指向谁, 参数1, 参数2, 参数3…) 第二个位置的参数, 会传递到函数中
2.apply()
语法 : 函数.apply(this指向谁, [参数1, 参数2, 参数3]) 第二个位置的数组内数据, 会传递到函数内部
3.bind()
语法 : 函数.bind(this指向谁, 参数1, 参数2, 参数3…) 第二个位置的参数开始, 会传递到函数中
注意:bind 方法不会立即执行函数, 他会返回一个 内部 this 修改完毕的 新函数
<script>
var obj = {
a: 1,
b: 2,
c: '我是对象obj的属性c'
}
function fn(x, y) {
console.log(this, x, y)
}
fn(100, 200)
fn.call(obj, 300, 400) ///call() --->{a: 1, b: 2, c: '我是对象obj的属性c'} 300 400
fn.apply(obj, [500, 600]) //apply() --->{a: 1, b: 2, c: '我是对象obj的属性c'} 500 600
var newFn = fn.bind(obj, 700, 800)
newFn() //bind() --->{a: 1, b: 2, c: '我是对象obj的属性c'} 700 800
</script>