使用JavaScript實現一個new

  • JavaScript的函數既可以作爲普通函數被調用,也可以作爲構造函數被調用。
  • 我們使用new運算符來調用函數時,此時的函數就是一個構造器。
  • JavaScript中絕大部分數據都是對象,那麼JavaScript中也一定會有一個根對象的存在,這些對象的鼻祖(根源)都來自於這個根對象。
  • JavaScript中的根對象是Object.prototype對象,而這個Object.prototype對象是一個空對象,追其根源,我們遇到的每一個對象都是從Object.prototype克隆而來的,Object.prototype對象就是他們的原型。
  • 原型鏈:從Object.prototype克隆除了A對象,我們又從A對象克隆出了B對象,實際上他們的關聯就是一個鏈路,彼此關聯,同時根原型就是Object.prototype。
  • 使用new運算符來創建對象的過程:實際上就是先去克隆Object.prototype對象,再進行一些其他額外操作的過程。

首先:

  1. 創建一個普通函數(使用它來當做構造函數)
function person(name) {
    this.name = name;
}

2.在它的原型上創建一個方法

person.prototype.getName = function () {
    return this.name
}
  1. 實現一個new
let _new = function () {
    // 從Object上克隆一個對象
    let obj = new Object();
    // 獲取外部傳入的構造器 person
    Constructor = [].shift.call(arguments);
    console.log(arguments);
    // 指向正確的原型:我們使用person對象創建的
    obj.__proto__ = Constructor.prototype;

    // 給obj設置屬性
    var ret = Constructor.apply(obj, arguments);

    // 返回這個對象
    return typeof ret === 'object' ? ret : obj;
};
  1. 驗證這個new是否創建成功
let obj_1 = _new(person, 'sven');

console.log(obj_1.name); // => sven
  1. 完整代碼
function person(name) {
    this.name = name;
}
person.prototype.getName = function () {
    return this.name;
};
let _new = function () {
    // 從Object上克隆一個對象
    let obj = new Object();
    // 獲取外部傳入的構造器 person
    Constructor = [].shift.call(arguments);
    console.log(arguments);
    // 指向正確的原型
    obj.__proto__ = Constructor.prototype;

    // 克隆構造器的屬性給obj
    var ret = Constructor.apply(obj, arguments);

    // 返回這個對象
    return typeof ret === 'object' ? ret : obj;
};
let obj_1 = _new(person, 'sven');
console.log(obj_1.name);
  • 7 可能會疑惑的地方

[].shift.call(arguments): 這個是獲取arguments對象的第一個參數,arguments是一個數組對象,但是它又不具備數組的一些方法,打印出來如下:
arguments

 {'0': [Function: person], '1': 'sven' }

借用array.prototype對象上的方法就可以完成shift操作,會給我們返回第一個值,也就是person對象,其他的值就是我們傳入的參數。

Constructor.apply(obj, arguments); :用來鏈接構造器,其實就是把剩下的參數也克隆給obj。

{"0":'sven'}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章