网站首页 > 技术文章 正文
前言
javascript 中 call / apply / bind 这三个方法是日常工作中比较实用的改变函数 this 指向的方法,很方便,但由于涉及到对 this 的理解,同时也是很容易出错的方法,也是面试官喜欢问的考题之一,今天就和大家一起好好聊一聊这三个方法
call / apply / bind 的区别
我们先简单的过一下他们之间的异同点,有个简单概念之后再详细分析
共同点
他们的功能一致,都是用来改变函数的 this 指向
// 语法
函数.call(thisArg, arg1, arg2, ...)
函数.apply(thisArg, [argsArray])
函数.bind(thisArg, [argsArray])
不同点
- call / apply 可以立即执行;bind 不会立即执行,而是返回一个函数,可以在需要的时候再执行
- 参数不同:apply 第二个参数是数组;call 和 bind 有多个参数需要用逗号隔开挨个写
简单应用场景
- 改写 this 指向,让目标对象使用一些方法
const person = {
name: '江',
say: function () {
console.log(this.name)
}
}
person.say() // 江
const obj = {
name: '李'
}
person.say.call(obj) // 李
person.say.apply(obj) // 李
person.say.bind(obj)() // 李
- 借用方法
const numbers = [5, 458 , 120 , -215 ];
const maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法
手写 call
Function.prototype.myCall = function (thisArg, ...argsArray) {
// 判断 thisArg 是否 null / undefine
if (thisArg === null || thisArg === undefined) {
thisArg = window
}
console.log(this) // 这里的 this 是调用的函数
thisArg.fn = this
thisArg.fn(...argsArray)
}
手写 apply
Function.prototype.myApply = function (thisArg, argsArray) {
// 判断 thisArg 是否 null / undefine
if (thisArg === null || thisArg === undefined) {
thisArg = window
}
console.log(this) // 这里的 this 是调用的函数
thisArg.fn = this
thisArg.fn(...argsArray)
}
手写 bind
Function.prototype.myBind = function (thisArg, argsArray) {
// 判断 thisArg 是否 null / undefine
if (thisArg === null || thisArg === undefined) {
thisArg = window
}
console.log(this) // 这里的 this 是调用的函数
thisArg.fn = this
return function () {
thisArg.fn(...argsArray)
}
}
使用一下我们手写的三个方法,看是否满足我们的要求
const person = {
name: '江',
say: function (word) {
console.log(this.name + ":" + word)
}
}
person.say('你好') // 江:你好
const obj = {
name: '李'
}
person.say.myCall(obj, 'hello') // 李:hello
person.say.myApply(obj, ['hello']) // 李:hello
person.say.myBind(obj, ['hello'])() // 李:hello
可以看到可以按期望输出结果了~
总结
对于改写 this 指向的实现,关键点是要理解:
- 我们自定义的方法,必须是挂载在 Function 这个个构造函数上的,这是一个大前提,因为只有这样,我们在任意方法上使用 . 才能找到我们的方法属性(其实就是原型链)
- 还有就是对当前函数里 this 的理解,这个场景可以简单理解为 this 是谁调用就指向谁,那么
- 函数.myCall() 就很清晰了,是函数调用了 myCall,所以 myCall 方法里的 this 指向的就是函数
- 理解了以上两点,就只要把 this(想执行的方法) 挂到我们的目标对象thisArg上面就可以了
猜你喜欢
- 2024-11-16 3.1 Python高级编程-函数式编程工具
- 2024-11-16 面向对象编程的一些思考(面向对象编程的理解)
- 2024-11-16 知识总结-Java8 Stream函数式编程
- 2024-11-16 bind、call、apply 区别?如何实现一个bind?
- 2024-11-16 Javascript基础重拾笔记之手写apply、call
- 2024-11-16 java 8新特性 常用内置函数式接口
- 2024-11-16 7、JavaScript 内置的常用对象有哪些?该对象常用的方法(必会)
- 2024-11-16 Java中“::”是什么含义(java中+是什么)
- 2024-11-16 Java 8 中的 Function:让代码从繁琐到简洁的魔法工具
- 2024-11-16 13万字详细分析JDK中Stream的实现原理(中)
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-