一些常见方法模拟实现

1、bind

注意:一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。


if (!Function.prototype.bind) { 
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
           // closest thing possible to the ECMAScript 5 
           // internal IsCallable function 
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 
    } 
    var aArgs = Array.prototype.slice.call(arguments, 1), 
    fToBind = this, 
    fNOP = function() {}, 
    fBound = function() { 
        return fToBind.apply(this instanceof fNOP ? this : oThis, // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
        aArgs.concat(Array.prototype.slice.call(arguments))); 
    }; // 维护原型关系 
    if (this.prototype) { 
       // Function.prototype doesn't have a prototype property 
       fNOP.prototype = this.prototype; 
     } 
     fBound.prototype = new fNOP(); 
     return fBound; 
   }; 
}



2、 new

new 操作符干了些什么:


创建一个新对象

将构造函数的作用域赋给新对象(将this指针指向这个新对象)

执行构造函数中的方法(为新对象添加属性)

返回这个新对象


模拟实现



funtion newFunc(){
    var obj = new Object();
    var Constructor = [].shift.call(arguments);
    obj.__proto__ = Contructor.prototype;
    var result = Constructor.apply(obj,arguments);
}



3、 call


call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。


步骤:将函数设为对象的属性 执行该函数 删除该函数



function callFunc(context){
    var context = context || window;
    context.fn = this;
    var args = [];
    for(var i = 0,len = arguments.length;i<len;i++){
        args.push('arguments['+i+']');
    }
    var result = eval('context.fn('+args+')');
    delete context.fn;
    return result;
}



4、apply


apply 跟 call 类似,只不过它传递的参数是数组



function applyFunc(context,arr){
    var context = context || window;
    context.fn = this;

    var result;
    if(!arr){
        result = context.fn()
    }else{
        var  args = [];
        for(var i =0,len = arr.length;i<len;i++){
            args.push('arr['+i+']');
        }
        result = eval('context.fn(' + args + ')');
    }
    delete context.fn;
    return result;
}




5、Array.map


Array.prototype.map = function(callback,thisArg){
    var T,A,K;
    if(this == null){
        throw new TypeError('this is null or not defined');
    }
    var O = Object(this);
    var len = O.length;
    if(Object.prototype.toString.call(callback) !== '[object Function]'){
        throw new TypeError(callback + 'is not a function');   
    }
    if(thisArg){
        T = thisArg;
    }
    A = [];
    k = 0;
    while( k < len){
        var kValue,mappedValue;
        if(k in O){
            mappedValue = callback.call(T,kValue,k,O);
        }
        A[k] = mappedValue;
        k++;
    }
    return A;
}



确认 取消
2条评论
sss