一、call、apply、bind 其作用都是改变函数运行时this的指向
1, call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔
2, apply 的所有参数都必须放在一个数组里面传进去
3, bind 除了返回是函数以外,它 的参数和 call 一样
二、手动实现三个函数
1, 回忆
1, 每个 JavaScript 函数实际上都是一个 Function 对象
console.log((function(){}).constructor === Function)
2, javascript的fn方法
对应JQuery:
jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。
jQuery.fn.extend(object);给jQuery对象添加方法。
可以理解为:jQuery.fn = jQuery.prototype
2,call 函数实现
Function.prototype.myCall = function(context) {
// 首先判断调用对象
if(typeof this !== 'function') {
console.log('type error')
}
// 获取参数
let args = [...arguments].slice(1); //第一个是对象,从第二个开始
result = null
// 判断content(this指针要指向的对象)是否传入, 如果没有设置为window
context = context || window
// 将调用函数设置为对象的方法
context.fn = this
// 调用函数
result = context.fn(...args);
// 删除属性
delete context.fn
return result
}
3, apply函数实现
Function.prototype.myApply = function (context) {
// 首先判断调用对象是否为函数
if(typeof this !== 'function') {
throw new TypeError('error')
}
let result = null
// 判断传入的对象是否存在,在浏览器中默认是window, 在node.js中默认是Object
context = context || window
// 把当前调用的函数赋值给传入对象的
// context.fn 可以理解为: context.prototype.
context.fn = this
if (arguments[1]) {
result = context.fn([...arguments[1]]) // 调用赋值的函数
}
delete context.fn
return result
}
4, bind函数实现
Function.prototype.myBind = function(context) {
if (typeof this !== 'function') {
throw new TypeError('error')
}
// 获取参数
let args = [...arguments].slice(1) // 第一个是对象
context.fn = this // 调用对象
return function Fn() {
return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))
}
}
5, 测试
var cat = {
name:"喵喵",
eatFish:function(param1,param2){
console.log("吃鱼");
console.log("this的指向=>");
console.log(this);
console.log(param1,param2);
}
}
var dog = {
name:"汪汪",
eatBone:function(param1,param2){
console.log("啃骨头");
console.log("this的指向=>");
console.log(this);
console.log(param1,param2)
}
}
cat.eatFish.myCall(dog,'汪汪','吃鱼,call')
cat.eatFish.myApply(dog,['汪汪','吃鱼,apply'])
let eatFun = cat.eatFish.myBind(dog,'汪汪','吃鱼','bind')
console.log(eatFun())
三, 总结
bind和call与apply的区别是不会立即调用函数,常用于改变回调函数的参数,bind的参数传递方式和call一样 箭头函数体内的 this 对象, 是定义时所在的对象, 而不是使用时所在的对象