call,apply,bind,new實現代碼

call

ES3實現方式javascript

Function.prototype.call = function (context) {
    context = context ? Object(context) : window; 
    context.fn = this;

    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
    var result = eval('context.fn(' + args +')');

    delete context.fn
    return result;
}
複製代碼

ES6實現方式java

Function.prototype.call = function (context) {
  context = context ? Object(context) : window; 
  context.fn = this;

  let args = [...arguments].slice(1);
  let result = context.fn(...args);

  delete context.fn
  return result;
}
複製代碼

apply

ES3實現方式app

Function.prototype.apply = function (context, arr) {
    context = context ? Object(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;
}
複製代碼

ES6實現方式函數

Function.prototype.apply = function (context, arr) {
    context = context ? Object(context) : window; 
    context.fn = this;
  
    let result;
    if (!arr) {
        result = context.fn();
    } else {
        result = context.fn(...arr);
    }
      
    delete context.fn
    return result;
}
複製代碼

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");
    }

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

    var fNOP = function () {};

    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}
複製代碼

new

function create() {
	// 一、得到構造函數,同時刪除 arguments 中第一個參數
    Con = [].shift.call(arguments);
	// 二、建立一個空的對象並連接到原型,obj 能夠訪問構造函數原型中的屬性
    var obj = Object.create(Con.prototype);
	// 三、綁定 this 實現繼承,obj 能夠訪問到構造函數中的屬性
    var ret = Con.apply(obj, arguments);
	// 四、優先返回構造函數返回的對象
	// 這是爲了應付構造函數有返回對象的狀況,下面給出實例
	return ret instanceof Object ? ret : obj;
};
複製代碼

new 第4點實例解釋

1.構造函數返回一個對象ui

function Car(color, name) {
    this.color = color;
    return {
        name: name
    }
}

var car = new Car("black", "BMW");
car.color;
// undefined

car.name;
// "BMW"
複製代碼

2.構造函數沒有return,返回undifinethis

function Car(color, name) {
    this.color = color;
}

var car = new Car("black", "BMW");
car.color;
// black

car.name;
// undefined
複製代碼

3.構造函數有返回值,可是返回的不是對象spa

function Car(color, name) {
    this.color = color;
    return "new car";
}

var car = new Car("black", "BMW");
car.color;
// black

car.name;
// undefined
複製代碼
相關文章
相關標籤/搜索