改变this指向的三种方法(call、apply、bind)
JavaScript 中允许指定(改变)函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向。
·
JavaScript 中允许指定(改变)函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向
一、call()
call的作用:使用 call 方法调用函数,同时指定被调用函数中 this 的指向
call的应用场景: Object.prototype.toString.call(数据) 检测数据类型
代码分享:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>改变this指向-call</title>
</head>
<body>
<script>
// 1. 改变this指向 - call
const obj = { name: '佩奇' }
// call() 作用: 第一个调用函数 第二改变this指向
function fun(x, y) {
console.log(this)
// console.log(x + y)
return x + y
}
fun() // this 指向window
// fun.call(obj) // this 指向 obj 对象
// fun.call(obj, 1, 2) // this 指向 obj 对象
console.log(fun.call(obj, 1, 2)) // 返回值就是函数 返回值
// 2. call的应用场景 - 检测数据类型
// 2.1 typeof 检测数据类型不够精确的
console.log(typeof '123') // string
console.log(typeof []) // object
console.log(typeof null) // object
// 2.2 Object.prototype.toString() 返回的结果是[object xxx类型]
// console.log(Object.prototype.toString('123')) // [object Object]
console.log(Object.prototype.toString.call('123')) // [object String]
console.log(Object.prototype.toString.call(123)) // [object Number]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(null)) // [object Null]
</script>
</body>
</html>
二、apply()
apply()的作用:使用 apply 方法调用函数,同时指定被调用函数中 this 的值
apply()的使用场景:apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
call和apply的区别是?
都是调用函数,都能改变this指向 参数不一样,call是传递参数列表,apply传递的必须是数组
call可以用来检测数据类型,apply可以求数组最大值
代码分享:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>改变this指向apply</title>
</head>
<body>
<script>
// 改变this指向apply
// 1. 基本使用
const obj = { name: '佩奇' }
function fun(x, y) {
console.log(this)
console.log(x + y)
}
fun()
// fun.apply() // 1. 作用1调用函数
// fun.apply(obj) // 2. 作用2 改变this指向 obj
fun.apply(obj, [1, 2]) // 参数必须是数组
// 2. 使用场景- 求数组的最大值/最小值
console.log(Math.max(...[1, 2, 3])) // 3
// apply 或者 call 如果不需要改变this指向 写 null
console.log(Math.max.apply(null, [8, 2, 3])) // 8
console.log(Math.min.apply(null, [8, 2, 3])) // 2
</script>
</body>
</html>
效果展示:
三、bind()
bind() 方法不会调用函数。但是能改变函数内部 this 指向
返回由指定的 this 值和初始化参数改造的 原函数拷贝 (新函数)
使用场景: 当我们只是想改变 this 指向,并且不想调用这个函数时,可以使用 bind,比如改变定时器内部的this指向.
代码分享:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>改变this指向-bind方法</title>
</head>
<body>
<button class="code">发送验证码</button>
<script>
const obj = { name: '佩奇' }
//改变this指向-bind方法
// 1. 基本使用
function fun(x, y, z) {
console.log(this)
console.log(x + y + z)
}
// fun()
// fun.bind() // bind不会调用函数
// const fn = fun.bind() // 返回的是对原来函数的拷贝
// console.log(fn)
// console.log(fn === fun) // false
// const fn = fun.bind(obj) // bind 可以改变this指向
const fn = fun.bind(obj, 1, 2, 3) //
fn() // 调用函数
// 2. 使用场景 - 不需要调用函数,但是又想改变函数内部的this指向
// 1. 发送短信5秒倒计时业务
const codeBtn = document.querySelector('.code')
let flag = true // 开关变量,用来防止多次点击
codeBtn.addEventListener('click', function () {
if (flag) {
// 1.2 利用定时器做倒计时效果 setInterval
let i = 5
// 点击之后立马变化文字
this.innerHTML = `05秒后重新获取`
// 定时器
let timerId = setInterval(function () {
i--
this.innerHTML = `0${i}秒后重新获取`
// 1.3 时间到了 就显示文字为 重新获取
if (i === 0) {
this.innerHTML = `重新获取`
// 停止定时器
clearInterval(timerId)
flag = true
}
}.bind(this), 1000)
// 关闭开关
flag = false
}
})
</script>
</body>
</html>
三种方法的总结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>this指向总结</title>
</head>
<body>
<button>点击</button>
<script>
// this指向总结
// 1. 普通函数
// 1.1 全局内调用
function fn() {
console.log(this) // window
}
fn()
// 1.2 对象内调用
const obj = {
name: '佩奇',
sayHi() {
console.log(this) // obj
}
}
obj.sayHi()
// 1.3 构造函数内this
function Person() {
this.name = name
console.log(this)
}
const zs = new Person()
// 1.4 事件处理函数中的this
document.querySelector('button').addEventListener('click', function () {
console.log(this)
})
// 1.5 特殊调用 call apply bind 可以改变this指向
const o = { name: '佩奇' }
function fun() {
console.log(this)
}
fun.call(o)
// 2. 箭头函数 没有this,是沿用上一级作用域的this
</script>
</body>
</html>
更多推荐
已为社区贡献3条内容
所有评论(0)