JavaScript淺析 -- new構(gòu)造對(duì)象

一、構(gòu)造對(duì)象的幾種方式

1.字面量法:
var person1 = {
    name: 'peter',
    age: 18,
    sex: 'boy',
    getAge: function() {
        return this.age;
    }
}
var person2 = {
    name: 'john',
    age: 22,
    sex: 'boy',
    getAge: function() {
        return this.age;
    }
}

字面量法就是簡(jiǎn)單的key:value直接創(chuàng)建,但是有以下兩個(gè)缺點(diǎn):

  • 構(gòu)造麻煩。每次操作都要給所有的變量賦值,都是重復(fù)操作的復(fù)制粘貼代碼很多。
  • 每個(gè)使用者都需要了解詳細(xì)的內(nèi)部細(xì)節(jié),即使只是想個(gè)性化改變下name。
2. 函數(shù)自動(dòng)化法:
function createPerson(name, age) {
    return {
        name: name,
        age: age,
        getAge: function() {
            return this.age;
        }
    }
}
var person1 = createPerson('peter', 18);
  • 優(yōu)點(diǎn):使用此法簡(jiǎn)化了構(gòu)造的過程,每次構(gòu)造只要調(diào)用函數(shù)并傳入對(duì)應(yīng)的參數(shù)即可。也不需要知道內(nèi)部實(shí)現(xiàn)的邏輯。
  • 缺點(diǎn):函數(shù)返回的都是一個(gè)Object類型的對(duì)象,辨識(shí)度不高。
3. 構(gòu)造函數(shù)法:
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.getAge = function() {
        return this.age;
    }
}
var person1 = new Person('peter', 18);

function Car(speed) {
    this.speed = speed;
}
var car1 = new Car(50);

用這種方法構(gòu)造出來的對(duì)象類型可以自由定義,比如上面的person1的類型對(duì)象是Person,car1是Car,很好區(qū)分。如果用第二種的話則他們的類型都是Object。

二、new的過程發(fā)生了啥

也許有些小伙伴會(huì)有疑惑,為啥會(huì)有個(gè)new,而不是直接執(zhí)行方法,這個(gè)new到底做了些啥?其實(shí),在new的過程中,主要做了這三件事:

  1. 創(chuàng)建一個(gè)空的對(duì)象,并將該對(duì)象的proto指向了Person.prototype。
  2. 執(zhí)行函數(shù),函數(shù)里面對(duì)this操作相當(dāng)于對(duì)這個(gè)新建的空的對(duì)象操作。
  3. 函數(shù)執(zhí)行完畢之后,返回這個(gè)空的對(duì)象。
原型圖

如上圖,是構(gòu)造函數(shù)法代碼的簡(jiǎn)單原型圖。每個(gè)對(duì)象都有一個(gè)_proto_,每個(gè)方法都有一個(gè)prototype,而new的最重要一步就是將生成空對(duì)象的_proto_指向了Person的prototype。

三、new一些補(bǔ)充

  1. new本身就能執(zhí)行構(gòu)造函數(shù),所以后面加不加括號(hào)都無所謂,但是為了表示是個(gè)函數(shù),推薦加上括號(hào)。
  2. 若構(gòu)造函數(shù)前不加new,則相當(dāng)于普通的執(zhí)行方法,就不再執(zhí)行上面說的new的過程,會(huì)導(dǎo)致其中的this不再指向?qū)嵗龑?duì)象,所以記得加new。若普通函數(shù)(內(nèi)部沒有this)加new,則返回一個(gè)空對(duì)象。
  3. 在構(gòu)造函數(shù)里,可以通過new.target獲得當(dāng)前的構(gòu)造函數(shù),若返回undefined則證明當(dāng)前沒有使用new操作。另一種方法是判斷this instanceof 構(gòu)造函數(shù),看是否返回true來判斷是否使用new,若為false則返回new 構(gòu)造函數(shù)()。
function f() {
  if (!new.target) {
    throw new Error('請(qǐng)使用 new 命令調(diào)用!');
  }
}
f(); // Uncaught Error: 請(qǐng)使用 new 命令調(diào)用!
  1. 構(gòu)造函數(shù)的最后不需要return。若加了return且返回了一個(gè)對(duì)象,則會(huì)用該對(duì)象替換當(dāng)前創(chuàng)建的實(shí)例對(duì)象。若返回基本數(shù)據(jù)類型則忽略返回原來實(shí)例對(duì)象。
var Human = function (){
  this.age = 18;
  return { age: 20 };
};
(new Human()).age; // 20

var Human = function () {
  this.age = 18;
  return 66;
};
(new Human()) === 66; // false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容