bind
1、bind会改变this 的指向为第一个参数 2、返回一个函数
Function.prototype.bind1 = function() {
//将参数解析未数组
const args = Array.prototype.slice.call(arguments);
// 获取this(取出数组的第一项,数组剩余的就是传递参数)
const t = arg.shift(); // 获取第一个参数
const self = this; // 当前函数的this
// 返回一个函数
return function() {
// 执行原函数,并返回结果
return self.apply(t, args);
}
}
call
call的特点 1、可以改变我们当前函数的this指向。 2、还会让当前的函数执行 3、每一个方法上面都会有一个call和applay方法,这是一个方法原型上的方法
Function.prototype.ownCall = function(context){ // 传的就是一个上下文,如果没有参数就是window
context = context ? Object(context) : window;
context.fn = this;
// 拿到参数
let args = [];
// 从1开始循环的原因是,第一个是我们的上下文,后面的才是我们的参数
for(let i = 1; i < arguments.length; i++) {
args.push('arguments['+i+']'); // 这样传进来的就是 // ['','',''];
}
// 利用数组的tostring方法
let r = eval('context.fn('+args+')') // eval是可以让字符串执行
delete context.fn;
return r
}
function mycall1(){
console.log(1, this);
}
function mycall2(){
console.log(2, this);
}
mycall1.ownCall(mycall2); // 1 // this指向了mycall2,并且执行mycall1
mycall1.ownCall.ownCall.ownCall(mycall2) // 2 // 执行的是mycall2
apply
1、apply和call的方法的区别是apply的第二个参数传的是一个数组 2、他们的第一个参数都是this指向
Function.prototype.ownApplay = function(context, args){ // 传的就是一个上下文,如果没有参数就是window
context = context ? Object(context) : window;
context.fn = this;
// 拿到参数 就是一个数组
if(!args) return context.fn();
// 利用数组的tostring方法
let r = eval('context.fn('+args+')') // eval是可以让字符串执行
delete context.fn;
return r
}
function mycall1(){
console.log(1, this);
}
function mycall2(){
console.log(2, this);
}
mycall1.ownApplay('hello', [1,2,3,4])