call
js
const Person1 = {
fullName: function (country, city) {
return this.firstName + this.lastName + " " + country + " " + city
}
}
const Person2 = {
firstName: "张",
lastName: "三",
}
Person1.fullName.call(Person2, '中国', '河南') // 张三 中国 河南
call的作用是改变了那个被执行的方法(也就是调用call的那个方法)的直接调用者!
而这个被执行的方法内部的this也会重新指向那个新的调用者,就是call方法所接收的第一个obj参数。
还有两个特殊情况就是当这个obj参数为null或者undefined的时候,this会指向window。
js
Function.prototype.myCall = function (obj) {
// 保存this 谁调用的myCall,this就指向谁,指向obj1.fun
obj.fn = this
// 保存参数
let args = Array.from(arguments).slice(1)
// 调用函数
let result = obj.fn(...args)
// 删除fn属性
delete obj.fn
return result
}
var obj1 = {
num: 20,
fun: function (n) {
return this.num + n
}
};
var obj2 = {
num: 15,
};
let res = obj1.fun.myCall(obj2, 10)
console.log(res);
apply
js
const person = {
fullName: function (country, city) {
return this.firstName + this.lastName + " " + country + " " + city
}
}
const newPerson = {
firstName: "壮",
lastName: "志国",
}
person.fullName.apply(newPerson, ['中国', '河南']) // 壮志国 中国 河南
js
Function.prototype.myApply = function (obj) {
let result
// 保存this 谁调用的myCall,this就指向谁,指向obj1.fun
obj.fn = this
// 是否传参
if (arguments[1]) {
result = obj.fn(...arguments[1])
} else {
result = obj.fn()
}
delete obj.fn
return result
}
var obj1 = {
num: 20,
fn: function (n, m) {
return this.num + n + m
}
};
var obj2 = {
num: 15,
};
let res = obj1.fn.myApply(obj2, [10, 20])
console.log(res);
bind
js
const person = {
fullName: function (country, city) {
return this.firstName + this.lastName + " " + country + " " + city
}
}
const newPerson = {
firstName: "壮",
lastName: "志国",
}
// 打印出fullName函数
person.fullName.bind(newPerson, '中国', '河南')() // 壮志国 中国 河南
js
Function.prototype.myBind = function (obj) {
// 这里的 this/self 指的是需要进行绑定的函数本身,比如用例中的 man
const self = this;
// 获取 myBind 函数从第二个参数到最后一个参数(第一个参数是 obj)
// 这里产生了闭包
const args = Array.from(arguments).slice(1)
return function () {
// 这个时候的 arguments 是指 myBind 返回的函数传入的参数
const bindArgs = [...arguments]
// 合并
return self.apply(obj, [...args, ...bindArgs]);
};
};
const person = {
name: 'zyj'
}
function man(age) {
console.log(this.name);
console.log(age)
}
const test = man.myBind(person)
test(18)//zyj 18