new原理分析

首先先來段我們熟悉的代碼

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('i can speak');
}


let girl = new Person('weboof', 18);

console.log(girl.name);
console.log(girl.age);
girl.say();

這是我們經常看到並且常用的代碼由此可以看出通過new創建出來的實例有以下幾個特徵:

  • new通過構造函數Person創造出來的實例可以訪問構造函數中定義的屬性和方法。
  • new通過構造函數Person創造出來的實例可以訪問構造函數原型上的屬性和方法。

接下來按照以上總結內容我們試着自己實現以下new操作符。首先我們需要了解以下幾個問題點:

  • 如何讓實例和構造函數產生關係如何實現屬性和方法的繼承?
  • 如何讓實例和構造函數的原型產生關聯?

簡易版

function creat(Construction, ...args){
    let obj = {};
    Construction.call(obj, ...args);  //繼承構造函數內部屬性和方法
    //Construction.apply(obj, args);  //繼承構造函數內部屬性和方法
    Object.setPrototypeOf(obj, Construction.prototype); //連接原型
    return obj;
}


function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('i can speak');
}


let girl = creat(Person, 'weboof', 18);

console.log(girl.name); //weboof
console.log(girl.age); //18
girl.say(); // i can speak

我們看到以上方法已經可以實現一個簡易的new操作符了。接下來我們還需要討論一下當構造函數有返回值時 會出現什麼情況?

構造函數返回原始類型

function Person(name, age) {
    this.name = name;
    this.age = age;
    return 1
}
Person.prototype.say = function(){
    console.log('i can speak');
}


let girl = new Person('weboof', 18);

console.log(girl.name); //weboof
console.log(girl.age); //18
girl.say(); //i can speak

由此我們可以看出如果構造函數返回值爲原始類型時對於創建出來的實例不會有任何影響。

構造函數返回對象類型

function Person(name, age) {
    this.name = name;
    this.age = age;
    return {
        name: 'hanhh'
    }
}
Person.prototype.say = function(){
    console.log('i can speak');
}


let girl = new Person('weboof', 18);

console.log(girl.name); //hanhh
console.log(girl.age); //undefined
girl.say(); //VM267:17 Uncaught TypeError: girl.say is not a function

由此可以看出如果構造函數返回的值爲對象類型通過構造函數創建出的實例是會受到返回值的影響並且不會繼承構造函數原型鏈上的屬性和方法。

完整代碼如下

function creat(con, ...args) {
  //con爲傳進來的構造函數
  let obj = {};
  //obj可以訪問構造函數上面的屬性和方法
  // let result = con.call(obj, ...args);
  let result = con.apply(obj, args);
  if(result instanceof Object) {
    return result;
  }else {
    Object.setPrototypeOf(obj, con.prototype); //obj可以訪問構造函數原型鏈上的屬性
    return obj;
  }
}

以上就是對new操作符的詳細解釋,希望對你有幫助~

 

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