相同之处
- 改变函数执行时的上下文(改变函数体内 this 的指向)
let name = '张三';
let age = 18;
let obj = {
name: '李四',
age: this.age,
fun: function (from, to) {
console.log(`${this.name + this.age}岁,来自${from}去往${to}`);
}
}
console.log(obj.name);
console.log(obj.age);
obj.fun();
console.log('================================');
let obj1 = {
name: '王五1',
age: 22
}
let obj2 = {
name: '王五2',
age: 33
}
let obj3 = {
name: '王五3',
age: 44
}
obj.fun.call(obj1, '杭州', '上海');
obj.fun.apply(obj2, ['杭州', '上海']);
obj.fun.bind(obj3, '杭州', '上海')(); // bind这个方法在IE6~8下不兼容
区别
- call、apply 的区别,接受参数的方式不一样
- bind 不立即执行,apply、call 立即执行
手写函数
// call 函数实现
Function.prototype.myCall = function(context) {
// 判断调用对象
if (typeof this !== "function") {
console.error("type error");
}
// 获取参数
let args = [...arguments].slice(1);
let result = null;
// 判断 context 是否传入,如果未传入则设置为 window
context = context || window;
// 将调用函数设为对象的方法
context.fn = this;
// 调用函数
result = context.fn(...args);
// 将属性删除
delete context.fn;
return result;
};
// apply 函数实现
Function.prototype.myApply = function(context) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
let result = null;
// 判断 context 是否存在,如果未传入则为 window
context = context || window;
// 将函数设为对象的方法
context.fn = this;
// 调用方法
if (arguments[1]) {
result = context.fn(...arguments[1]);
} else {
result = context.fn();
}
// 将属性删除
delete context.fn;
return result;
};
// bind 函数实现
Function.prototype.myBind = function(context) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 获取参数
var args = [...arguments].slice(1),
fn = this;
return function Fn() {
// 根据调用方式,传入不同绑定值
return fn.apply(
this instanceof Fn ? this : context,
args.concat(...arguments)
);
};
};
应用
call、apply、bind 的应用
网友评论