一.call
// 原理:就是利用 “点”定THIS机制,context.xxx=self “obj.xxx=func” => obj.xxx()
Function.prototype.call = function call(context, ...params) {
// this/self->func context->obj params->[10,20]
let self = this,
key = Symbol('KEY'),
result;
context == null ? context = window : null;
!/^(object|function)$/i.test(typeof context) ? context = Object(context) : null;
context[key] = self;
result = context[key](...params);
delete context[key];
return result;
};
二.apply
// 原理:就是利用 “点”定THIS机制,context.xxx=self “obj.xxx=func” => obj.xxx()
Function.prototype.apply= function call(context, params) {
// this/self->func context->obj params->[10,20]
let self = this,
key = Symbol('KEY'),
result;
context == null ? context = window : null;
!/^(object|function)$/i.test(typeof context) ? context = Object(context) : null;
context[key] = self;
result = context[key](params);
delete context[key];
return result;
};
三.bind
// 原理:就是利用 “点”定THIS机制,context.xxx=self “obj.xxx=func” => obj.xxx()
Function.prototype.bind = function bind(context, ...params) {
// this/self->func context->obj params->[10,20]
let self = this;
return function proxy(...args) {
// 把func执行并且改变this即可 args->是执行proxy的时候可能传递的值
self.apply(context, params.concat(args));
};
};
提升:
鸭子类型
数组方法:slice forEach等在类数组类型中无法使用
Array.prototype.slice = function slice() {
let result = [];
for (let i = 0; i < this.length; i++) {
result.push(this[i]);
}
return result;
};
// 克隆arr返回一个新数组
// arr.slice();
/*
将类数组变成数组
// 类数组像数组「结构、一些操作...」,我们让其用数组上的方法「不能直接用」
function func() {
// console.log(arguments);
// 把arguments变为数组,这样就可以用数组的办法了:Array.from/[...arguments]/...
/!* let result = [];
for (let i = 0; i < arguments.length; i++) {
result.push(arguments[i]);
} *!/
// Array.prototype.slice -> [].slice
let result = Array.prototype.slice.call(arguments);
console.log(result);
[].forEach.call(arguments, item => {
console.log(item);
});
}
func(10,20,30)