回复下方公众号【面试宝典】,即可获取为你整理的107页后端笔试题。
之前我们说的就是代码中this的默认点
明天我们就来说说如何改变这个方向
也就是说,我不管你指哪里,你必须指我告诉你指的地方
开始
函数原型(Function.prototype)有三种方式
既然是函数的原型上,那么只要是函数,就可以调用这三个方法。 他们三个的作用就是改变函数的this点
那么我们就开始介绍这三种方法
规划一个功能
const obj = { name: '对象' }
const arr = [ 100, 200, 300 ]
function fn(a, b) {
console.group('fn 函数内的打印信息')
console.log('a : ', a)
console.log('b : ', b)
console.log('this : ', this)
console.groupEnd()
}
fn(1, 2)
直接调用函数,根据this指向规则,函数中的this会指向窗口
通话模式
句型:function.call(函数中的this点,传递给函数的参数,传递给函数的参数)
功能:改变函数中的this点
fn.call(obj, 1, 2)
借助call调用fn函数,此时obj就是fn函数中的this点
应用方法
句型:function.apply(函数中的点javascript传递数组,链表数据结构)
功能:改变函数中的this点
虽然apply和call方法本质上是一样的,只是给函数传递参数的方法不同而已。 apply的第二个参数是一个链表的数据结构,只要按照索引排列即可
数据结构中的每一个依次都是为函数赋值形参的数据
fn.apply(arr, [ 10, 20 ])
使用apply调用fn函数,此时arr就是fn函数中的this,第二个参数是一个链表
绑定方法
语句模式:function.bind(函数中的this,传递给函数的参数,传递给函数的参数)
功能:改变函数中的this点
虽然bind本质上和call方法是一样的,并且bind不会立即调用该函数,而是返回一个已经锁定了this的新函数
const res = fn.bind(obj, 100, 200)
使用bind调用fn函数,此时obj就是你要设置的fn函数中的this点
然而,虽然fn函数不会立即执行,但是根据fn函数再现了一个相同的函数,新函数被复制到res变量中,并且res函数中的this被锁定为obj。
通过浏览器查看,我们会发现fn函数并没有被调用。 那是因为bind本身不会调用fn函数。 如果想指向它,需要通过res变量来调用
res()
构造
前面我们介绍了这三种方法的用法。 如果你能把握好的话,我们就来看看这三种方法是如何实现的。
调用方法构造
// thisArg 拿到的是你要改变的 this 指向
// args 拿到剩下所有的内容, 是负责传递给目标函数的
Function.prototype.myCall = function (thisArg, ...args) {
thisArg = thisArg || windon // 如果没有这个参数, 就设置为 window
const fnKey = Symbol('fn') // 创建一个唯一 key 作为函数的标识
thisArg[fnKey] = this // 利用唯一标识把当前函数添加到指定对象中
const res = thisArg[fnKey]( ...args ) // 利用对象和唯一标识来调用函数, 这样就相当于对象在调用函数, this 指向自然被改变了, 在这里不要忘了把给函数准备的参数传递进去, 并且接受一下返回值
delete thisArg[fnKey] // 用完以后就删除掉这个临时对象成员
return res // 把接受到的函数返回值返出去就可以了
}
这样我们的调用构建就完成了
应用方式构建
这看起来和call方法类似,只是参数不同,但是根据调用方法的不同javascript传递数组,我们不再需要接受参数...args,直接接收即可
// thisArg 拿到的是你要改变的 this 指向
// args 拿到剩下所有的内容, 是负责传递给目标函数的
Function.prototype.myApply = function (thisArg, args) {
thisArg = thisArg || windon // 如果没有这个参数, 就设置为 window
const fnKey = Symbol('fn') // 创建一个唯一 key 作为函数的标识
thisArg[fnKey] = this // 利用唯一标识把当前函数添加到指定对象中
const res = thisArg[fnKey]( ...args ) // 利用对象和唯一标识来调用函数, 这样就相当于对象在调用函数, this 指向自然被改变了, 在这里不要忘了把给函数准备的参数传递进去, 并且接受一下返回值
delete thisArg[fnKey] // 用完以后就删除掉这个临时对象成员
return res // 把接受到的函数返回值返出去就可以了
}
绑定方式构建
虽然这个方法很简单,但是使用之前构建的call或者apply方法就可以了。
// thisArg 拿到的是你要改变的 this 指向
// args 拿到剩下所有的内容, 是负责传递给目标函数的
Function.prototype.myApply = function (thisArg, ...args) {
const fn = this // 利用一个变量把目标函数保存下来
// 返回一个新的函数即可
return function (...innerArgs) {
// 利用 myApply 方法调用目标函数, 并且优先初始传递的参数
return fn.myApply(fn, [ ...args, ...innerArgs ])
}
}
至此,bind的构建就完成了,是不是很简单!
-前锋教育-
近期新课程:
HTML5+CSS 基础知识|JavaScript|计算机基础知识
Vue2.0+Vue3.0|陌陌小程序|陌陌公众号开发|Node.js|node.JS前端|React基础|React项目|Webpack基础|Webpack中级
Vite2|TypeScript 教程|Node.JS|Flutter|Mpvue 教程