call、apply、bind的使用方法及区别
作用:这三个函数的作用都是用来改变this的指向
call使用方法
function fn1() {
console.log(this)
}
const obj = { a: 1 }
fn1.call(obj, 1, 2, 3, 4) // {a: 1}
apply的用法
function fn1() {
console.log(this)
}
const obj = { a: 1 }
fn1.apply(obj, [1, 2, 3, 4]) // {a: 1}
bind的用法
function fn1() {
console.log(this)
}
const obj = { a: 1 }
fn1.bind(obj, 1, 2, 3, 4) // 不会打印任何东西。
乍一看,三者的用法几乎一致,需要注意的是bind函数,调用之后并没有执行fn1
先看call和apply, 它们仅有的区别是传参的不同,call接收的是参数逐一传入,apply接收的是一个参数组成的数组
接下来,来实现自己的call和apply函数,通过用法发现需要实现两点:
- 改变执行函数的this指向为第一个参数
- 执行原函数
第二点好实现,来看第一点,通常情况下,当函数作为对象的方法调用时,this就指向这个对象,可以通过这个特点来实现自己的call函数
// 因为需要所有函数都可以调用,所以需要写在Function的原型上
Function.prototype.myCall(context) {
// 判断context是否存在,不存在设置为window
context = context ? Object(context) : window
// 处理参数
const args = [...arguments].slice(1)
// 要将this指向改为context,需要用context来调用
context.fn = this // 这里的this是原函数
const result = context.fn(...args) // 执行原函数,此时因为是context调用,因此函数中的this指向了context
delete context.fn
return result
}
实现自己的apply函数只需要修改传参方式即可
// 因为需要所有函数都可以调用,所以需要写在Function的原型上
Function.prototype.myCall(context) {
// 判断context是否存在,不存在设置为window
context = context ? Object(context) : window
// 要将this指向改为context,需要用context来调用
context.fn = this // 这里的this是原函数
let result
// 处理参数
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
接下来实现bind函数,bind与前两者较大不同是它创建了一个新的函数,并且它第一个参数被指定为这个新函数的this
- 返回一个新函数
- 第一个参数被指定为新函数的this
- 其余参数被当作新函数的参数
Function.prototype.myBind(context) {
const args = [...arguments].slice(1)
const that = this
return function() {
that.apply(context, args.concat(...arguments))
}
}
接下来了解一下new运算符
new的用法
function Animal(type) {
this.type = type
this.age = age
}
const animal1 = new Animal('猫', 2)
const animal2 = new Animal('狗', 2)
当执行new Animal()的时候,做了以下几件事情
- 创建一个空对象
- 改变this指向到这个空对象,并且让这个对象能访问到构造函数原型上的属性
- 执行构造函数,此时的this指向了新创建的对象
模拟生成new函数
function _new() {
// 创建一个新对象
let obj = {}
// 获取传入的构造函数
let constructor = [].shift.call(arguments)
// 让这个对象能访问到构造函数原型上的属性
obj.__proto__ = constructor.prototype
// 改变this指向,并执行构造函数
constructor.apply(obj, aruguments) // 这里的arguments已经经过截取处理
// 返回创建的实例对象
return obj
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!