Bind / Call / Apply
手写 call
原生 call
var foo = {
name: 'chou',
};
function sayName() {
console.log(this.name);
}
sayName.call(foo); // chou实现
手写 apply
思路
实现
手写 bind
第一版
第二版
第三版
Last updated
var foo = {
name: 'chou',
};
function sayName() {
console.log(this.name);
}
sayName.call(foo); // chouLast updated
var foo = {
name: 'chou',
}
function sayName() {
console.log(this.name)
}
------------------------
// 改造foo对象
var foo = {
name: 'chou',
sayName() {
console.log(this.name)
}
}
foo.sayName() // chouFunction.prototype._call = function (context) {
context.fn = this;
context.fn();
delete context.fn;
};Function.prototype._call = function (context) {
var args = [];
// 从第二个参数开始 因为第一个存放的是我们的函数
for (let i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
context = context || window;
context.fn = this;
context.fn(...args);
delete context.fn;
};Function.prototype._apply = function (context) {
var args = arguments[1];
context = context || window;
context.fn = this;
if (!args) {
context.fn();
} else {
if (args instanceof Array) {
context.fn(...args);
} else {
try {
throw new Error('CreateListFromArrayLike called on non-object');
} catch (e) {
console.log(e);
}
}
}
delete context.fn;
};Function.prototype._bind = function (context) {
var self = this;
return function () {
return self.apply(context);
};
};Function.prototype._bind = function (context) {
var self = this;
// 获取第二个参数到最后一个参数 第一个为函数 我们需要传入的变量
var args = Array.prototype.slice.call(arguments, 1);
return function () {
// 这个时候的arguments是指bind返回的函数传入的参数
var bindArgs = Array.prototype.slice.call(arguments);
// 用concat合并两次的参数
return self.apply(context, args.concat(bindArgs));
};
};