apply & call & bind 原始碼

班主任發表於2019-11-20

apply & call & bind 原始碼

  • call 原始碼
  • eval 是全域性物件上的一個函式,會把傳入的字串當做 JavaScript 程式碼執行。如果傳入的引數不是字串,它會原封不動地將其返回
// call原始碼
Function.prototype.call = function(context) {
    // 獲取上下文中的引數
    var context = context || window;
    // 儲存當前上下文
    context.fn = this;

    // 引數陣列
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']');
    }
    // 執行方法(es3語法) var result = context.fn(...args); // es6語法
    var result = eval('context.fn('+args+')');

    // 刪除繫結的上下文屬性
    delete context.fn;
    return result;
}
複製程式碼
  • apply 原始碼
Function.prototype.apply = function(context, arr) {
    var context = Object(context) || window;
    // 將當前上下文物件儲存
    context.fn = this;

    var result;
    if (!arr) { // 未傳引數
        result = context.fn();
    } else {
        var args = [];
        for (var i = 0; i < arr.lenght; i++) {
            args.push('arr['+ i + ']');
        }
        result = eval('context.fn('+ args +')');
    }
    delete context.fn;
    return result;
}
複製程式碼
  • bind原始碼
Function.prototype.bind = function (context) {
    
    var ctx = context;
    if (typeof ctx !== 'function') {
        throw new TypeError('Type Error!');
    }
    var self = this;
    function fn() {};
    // 繼承呼叫者原型上的方法
    fn.prototype = this.prototype;
    var bound = function(args) {
        return self.apply(context, args || null);
    }
    bound.prototype = new fn();
    return bound;
}
複製程式碼

相關文章