首先需要了解
相同点
call apply bind 三个函数 都是起着改变this指向的作用
不同点
1.call和apply的传参不同,call(对象,参数1,参数2,…)调用支持多参,而apply只支持2个参数apply(对象,传参数组)
[function].call([object],参数1,参数2,…参数n)
[function].apply([object],[参数1,参数2,参数3,…参数n])
2.call和apply改变的是一个函数调用的this指向,bind返回一个this指向已经改变的新函数
this指向改变原理
在js中 function中的this 谁调用this就指向谁 无人调用this默认指向window
object.function() 对象调用函数 那么这个function中的this就指向这个对象
加入原型写法
Function.prototype.myCall = function (obj, ...args) {
//先判断 obj中是否有值 如果有 就赋值指向 如果没有 就指向window
let callThis = (obj !== null & obj !== undefined) ? Object(obj) : window
//this 谁调用这个方法this就指向谁 所以这里this就是改变this指向的桉树
const fn = this
//将需改变this指向函数 放入callThis中
callThis.fn = fn
//这样去调用就可以改变this的指向
const result = callThis.fn(...args)
//调用完成之后 将callThis中的fn删除
delete callThis.fn
//有的函数是有返回值的 所以这里需要把返回值考虑进来
return result
}
Function.prototype.myApply = function (obj, arr) {
//apply接收的参数是arr 所以这里需要转数组
let callThis = (obj !== null & obj !== undefined) ? Object(obj) : window
//this 谁调用这个方法this就指向谁 所以这里this就是改变this指向的桉树
const fn = this
//将需改变this指向函数 放入callThis中
callThis.fn = fn
//这样去调用就可以改变this的指向
const result = callThis.fn(...arr)
//调用完成之后 将callThis中的fn删除
delete callThis.fn
//有的函数是有返回值的 所以这里需要把返回值考虑进来
return result
}
//bind函数 返回的是一个改变this指向的函数
Function.prototype.myBind = function (obj, ...Array) {
//先判断传值
let callThis = (obj !== null & obj !== undefined) ? Object(obj) : globalThis
const fn = this
function fnProxy(...args) {
callThis.fn = fn
//函数执行时调用
const result = callThis.fn([...Array, ...args])
return result
}
//将函数返回
return fnProxy
}
const obj = {
name: "wsm"
}
const foo = function () {
console.log(this);
}
const sum = function (n1, n2) {
console.log(this, n1, n2);
return n1 + n2
}
sum.myApply(obj, [12, 13])
console.log('结果', sum.myApply(obj, [12, 13]));
单独手写call
//定义一个加减方法
function add(a,b){
return a+b+this.c
}
const obj ={
c:10
}
//定义自己的call函数(参数1:要改变this指向的函数,this指向的对象,函数的参数)
const call = function (func,obj,...args){
//先判断 是否传入了obj 如过没有 就将window传进去
if(obj == null || obj ==undefined){
//globalThis 会根据环境自动识别 在浏览器环境就是window 在node环境globalProject
obj = globalThis
}
//第一步 将传入的函数拷贝给对象中
obj.test=func
//第二步 用对象.函数的方法调用该函数并传参返回
const result = obj.test(...args)
//每次调用完删除加入的函数
delete obj.test
//返回计算结果
return result
}
console.log(call(add,obj,10,10));
单独手写apply
和call差不多 只不过 传递的参数不同
//定义一个加减方法
function add(a,b){
return a+b+this.c
}
const obj ={
c:10
}
//定义自己的call函数(参数1:要改变this指向的函数,this指向的对象,函数的参数)
const call = function (func,obj,args){
//只有此处和call有区别
//先判断 是否传入了obj 如过没有 就将window传进去
if(obj == null || obj ==undefined){
//globalThis 会根据环境自动识别 在浏览器环境就是window 在node环境globalProject
obj = globalThis
}
//第一步 将传入的函数拷贝给对象中
obj.test=func
//第二步 用对象.函数的方法调用该函数并传参返回
const result = obj.test(...args)
//每次调用完删除加入的函数
delete obj.test
//返回计算结果
return result
}
console.log(call(add,obj,10,10));