如果忘了怎么实现call apply bind,就来看这篇文章

我心飞翔 分类:javascript

一、实现call

call 和 apply 和 bind其实就是改变函数的作用域。个人记忆法 叫的和绑定的只能一个个叫或者绑定,申请的话,可以一次申请多个。记这三个方法的 传参区别。bind函数调用,返回的是函数,并没有执行。

思路:整体的思路就是在调用的作用域下添加一个新函数并调用,然后删除。要处理context 为null时咋办,处理传参时候咋办,bind的时候还要想到返回的是个函数,并且可以被new,new了之后this的指向要变为 指向实例,还要用空函数来处理 prototype的继承。

call实现

Function.prototype.call2 = function (context) {
    var context1 = context || window;
    context1.fn = this;
    console.log(arguments)

    var result = context1.fn(...([...arguments].slice(1)));

    delete context1.fn
    return result;
}

// 测试一下
var value = 2;

var obj = {
    value: 1
}

function bar1(name, age) {
    console.log(this.value);
    return {
        value: this.value,
        name: name,
        age: age
    }
}

bar1.call2(null); // 2

console.log(bar1.call2(obj, 'kevin', 18));
 

apply实现

Function.prototype.apply2 = function(context, arr) {
    console.log(context);
    let context1 = context || window;
    console.log(this);
    context1.fn = this;
    let res;
    if (!arr) {
        context1.fn();
    } else {
        let args = Array.prototype.slice(arguments, 1);
        res = eval('context1.fn(' + args + ')');
    }
    delete context1.fn;
    return res;
};
let  foo = {value: 21};
let bar = function() {
    console.log(this.value);
}
bar();
bar.apply2(foo);
//undefined
//VM1169:2 {value: 21}
//VM1169:4 ƒ () {
//    console.log(this.value);
//}
//VM1169:18 21
 

bind实现

Function.prototype.bind2 = function(context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
let self = this;
let args = [...arguments].slice(1);
let fNop = function(){};
let fbind = function() {
let argBind = [...arguments].slice();
self.apply(this instanceof fNop ? this : context, args.concat(argBind));
}
fNop.prototype = this.prototype;
fbind.prototype = new fNop();
return fbind;
}
var value = 2;
var foo12 = {
value: 1
};
function bar12(name, age) {
this.habit = 'shopping';
console.log(this.value);
console.log(name);
console.log(age);
}
bar12.prototype.friend = 'kevin';
var bindFoo = bar12.bind2(foo12, 'daisy');
var obj = new bindFoo('18');
// undefined
// daisy
// 18
console.log(obj.habit);
console.log(obj.friend);

回复

我来回复
  • 暂无回复内容