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();

這是我們經(jīng)??吹讲⑶页S玫拇a,由此可以看出通過new創(chuàng)建出來的實例有以下幾個特征:

  • new通過構(gòu)造函數(shù)Person創(chuàng)造出來的實例可以訪問構(gòu)造函數(shù)中定義的屬性和方法。
  • new通過構(gòu)造函數(shù)Person創(chuàng)造出來的實例可以訪問構(gòu)造函數(shù)原型上的屬性和方法。

接下來,按照以上總結(jié)內(nèi)容我們試著自己實現(xiàn)以下new操作符。首先我們需要了解以下幾個問題點:

  • 如何讓實例和構(gòu)造函數(shù)產(chǎn)生關(guān)系,如何實現(xiàn)屬性和方法的繼承?
  • 如何讓實例和構(gòu)造函數(shù)的原型產(chǎn)生關(guān)聯(lián)?

簡易版

function creat(Construction, ...args){
    let obj = {};
    Construction.call(obj, ...args);  //繼承構(gòu)造函數(shù)內(nèi)部屬性和方法
    //Construction.apply(obj, args);  //繼承構(gòu)造函數(shù)內(nèi)部屬性和方法
    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

我們看到以上方法已經(jīng)可以實現(xiàn)一個簡易的new操作符了。接下來我們還需要討論一下,當(dāng)構(gòu)造函數(shù)有返回值時, 會出現(xiàn)什么情況?

構(gòu)造函數(shù)返回原始類型

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

由此,我們可以看出,如果構(gòu)造函數(shù)返回值為原始類型時,對于創(chuàng)建出來的實例不會有任何影響。

構(gòu)造函數(shù)返回對象類型

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

由此可以看出如果構(gòu)造函數(shù)返回的值為對象類型,通過構(gòu)造函數(shù)創(chuàng)建出的實例是會受到返回值的影響,并且不會繼承構(gòu)造函數(shù)原型鏈上的屬性和方法。

完整代碼如下

function creat(con, ...args) {
  //con為傳進來的構(gòu)造函數(shù)
  let obj = {};
  //obj可以訪問構(gòu)造函數(shù)上面的屬性和方法
  // 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可以訪問構(gòu)造函數(shù)原型鏈上的屬性
    return obj;
  }
}

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容