1. Handwritten bind:
Function.prototype.myBind = function () {
if (typeof this != 'function') {
throw new TypeError('ERROR');
}
//获取传递的参数
//Array.from()
//1.复制数组,如果传的是数组,将把数组复制一份传给新数组。
//2.如果是伪数组,将会转成数组在赋给新数组。
// 获取参数
const args = Array.from(arguments);
//要改变的this指向
const target = args.shift();
console.log('目标this',target);//{ name: 'xx' }
console.log('其余参数',args);//[ 1, 2, 3 ]
//调用它的函数
const self = this;
//返回一个函数
return function F() {
// 因为返回的这个函数,我们可以 new F(),所以需要判断
if (this instanceof F) {
console.log('...',...args)
// 对于 new 的情况来说,不会被任何方式改变 this
return new self(...args);
} else {
return self.apply(target,args)
}
}
}
// 普通函数
function print() {
console.log('this中的name',this.name);
}
let F = print.myBind({
name: 'xx'}, 1, 2, 3);
// 返回对象
let obj1 = F();
console.log(obj1);
// let obj2 = new F();
// console.log('obj2',obj2);
let obj2 = new F();
console.log('obj2',obj2);
2. Handwriting apply:
The subsequent parameters passed by apply are in the form of an array (passing a single value will report an error)
Function.prototype.myApply = function(context){
if (typeof this !== 'function'){
throw new TypeError('ERROR');
}
console.log(context);//要更改的this指向
context = context || window;
console.log(this)
context.fn = this;//新增fn属性,将值设置为调用apply的函数
let result;
//判断是否有参数
if(arguments[1]){
console.log(...arguments[1]);
result = context.fn(...arguments[1]);
}else{
result = context.fn();
}
delete context.fn
return result;
}
// 普通函数
function print(age,age2,age3){
console.log(this.name+" "+ age + " "+ age2+" "+age3); }
// 自定义对象
var obj = {
name:'xx' }
print.myApply(obj,[1,2,3])
3. Handwritten call:
Function.prototype.myCall = function (context) {
if (typeof this != 'function') {
throw new TypeError('Error');
}
context = context || window;
const args = Array.from(arguments).slice(1);
context.fn = this;
let result = context.fn(...args);
delete context.fn;
return result;
}
function print(age){
console.log(this.name +''+age);
}
print.myCall({
name:'xx'},1,2,3);