call,apply,bind 实现

call,apply,bind 实现

/**
 * 实现
 * call , 
 * apply ,
 *  bind
 */

 var c = {
     name:'huge',
     age:1236
 }
 var d = {
    name:'huge',
    age:1236
}


 function Person(sex,hobby,other){
     this.other = other;
     this.sex = sex;
     this.hobby = hobby;
     this.wife = "五";
 }

 Function.prototype.myCall = function(context){

    //不传默认为window
    var context = context || window,
        result;
    context.myFnTmp = this;
    // ES6 的话 用如下方法展开;
    // var args = Array.prototype.slice.call(arguments,1);
    // result = context.myFnTmp(...args);

    // 用eval
    var args =[];
    for(var i = 1;i < arguments.length; i++){
        args.push("arguments["+i+"]");
    }
    result = eval("context.myFnTmp("+args+")")
    delete context.myFnTmp;
    return result;
 }
//  Person.myCall(c,'女','00');
//  Person.myCall(d,'男','99');
//  console.log(c); console.log(d);

 Function.prototype.myApply =function(context,arr){
    //不传默认为window
    var context = context || window,
        result;
    context.myFnTmp = this;
   
    // 用eval
    var arr =arr || [],
        args = [];
    for(var i = 0;i < arr.length; i++){
        args.push("arr["+i+"]");
    }
    result = eval("context.myFnTmp("+args+")")
    delete context.myFnTmp;
    return result;
 }
//   Person.apply(c,['女','00']);
//  Person.myApply(d,['男','99']);
//  console.log(c); console.log(d);

// 缺陷 ; 当执行实例化操作时,丢失属性
 Function.prototype.myBind = function(context){
    var args = Array.prototype.slice.call(arguments,1),
        self = this;

    return function(){
        var newArgs =  Array.prototype.slice.call(arguments);
        self.myApply(context,args.concat(newArgs))
    }
 }

//缺陷 ;会修改原来的函数原型
 Function.prototype.myBind = function(context){
    var args = Array.prototype.slice.call(arguments,1),
        self = this;

    var fn =  function(){
        var newArgs =  Array.prototype.slice.call(arguments);
        // 当 new 时,this指向新的实例,所以要换上下文,变为实例对象
        self.myApply(this instanceof self ? this : context,args.concat(newArgs))
    }

    // 需要统一原型的构造函数,使上述的instanceof 成立
    fn.prototype = this.prototype;
    return fn;
 }
 //缺陷 ;会修改原来的函数原型
 Function.prototype.myBind = function(context){
  

    var args = Array.prototype.slice.call(arguments,1),
        self = this,
        tmp = function(){};

        tmp.prototype = this.prototype;
    var fn =  function(){
        var newArgs =  Array.prototype.slice.call(arguments);
        // 当 new 时,this指向新的实例,所以要换上下文,变为实例对象
        self.myApply(this instanceof self ? this : context,args.concat(newArgs))
    }

    // 需要统一原型的构造函数,使上述的instanceof 成立
    // 圣杯模式;隔离原型
    fn.prototype = new tmp();
    return fn;
 }
 var pp = Person.bind(c,'女','00');
 var ppp1 = new pp('拿三个呢')
 console.log(ppp1);
 var pp1 = Person.myBind(d,'女','00');
 var ppp2 = new pp1('拿三个呢')
 console.log(ppp2);console.log(pp); console.log(pp1);

猜你喜欢

转载自www.cnblogs.com/guyuedashu/p/13170247.html