1、示例
var zs = {
name: "张三",
say: function (gender, age) {
console.log(this.name + ',' + gender + ',' + age);
}
}
var ls = {
name: "李四",
}
2、释义
- call
接收多个参数,第一个参数为函数上下文this,后边参数为函数本身的参数。
// 示例:
zs.say.call(ls, "男", "16"); // "李四,男,16"
- apply
接收两个参数,第一个参数为函数上下文this,第二个参数为函数参数只不过是通过一个数组的形式传入的。
// 示例:
zs.say.apply(ls, ["男", "16"]); // "李四,男,16"
- bind
接收多个参数,第一个是bind返回值,返回值是一个函数上下文的this,不会立即执行。
// 示例1:
zs.say.bind(ls,"男","16")(); // "李四,男,16"
// 示例2:
zs.say.bind(ls,"男")("16"); // "李四,男,16"
// 示例3:
zs.say.bind(ls)("男","16"); // "李四,男,16"
这个看着是不是有点眼熟,对啦,和我们之前说的柯里化是不是一样呀;
下面我们手写下这几个方法试试
3、手写
- call
Function.prototype.call = function (context, ...args) {
//若没有传入对象,则绑定到window上
context = context || window
//唯一值
const fnSymbol = Symbol("fn");
//把函数赋值到对象的某个属性
context[fnSymbol] = this;
// 执行
context[fnSymbol](...args);
//删除fn声明
delete context[fnSymbol];
}
- apply
Function.prototype.apply = function (context, args) {
//若没有传入对象,则绑定到window上
context = context || window
//唯一值
const fnSymbol = Symbol("fn");
//把函数赋值到对象的某个属性
context[fnSymbol] = this;
// 执行
context[fnSymbol](...args);
//删除fn声明
delete context[fnSymbol];
}
- bind
Function.prototype.bind = function (context) {
// 保存this
let self = this
// 保存参数
let arg = [...arguments].slice(1)
return function () {
let newArg = [...arguments]
// 传入两次的参数
return self.apply(context, arg.concat(newArg))
}
}
如有疑问或不足之处,欢迎交流指正