您好,登錄后才能下訂單哦!
本篇內容主要講解“JavaScript對象的構造函數和new操作符怎么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript對象的構造函數和new操作符怎么用”吧!
前文講到的對象創建方法都是直接使用let obj = {...}
語法,具體方法如下:
let user = { name:'xiaoming', ...}
這樣的對象創建方法雖然簡單又直接,但是對象的代碼無法重用,在創建很多類似對象時,代碼量會很高。
此時,就需要使用構造函數,和new
操作符實現相似對象的構建。
如果學習過其他面向對象語言的童鞋對構造方法應該都不陌生,尤其是學習C++
的童鞋應該印象會非常深刻。
在其他面向對象的語言中,構造函數通常是這樣定義的:
構造函數是一個特殊的成員函數,名字與類名相同,創建類類型對象時由編譯器自動調用,保證每個數據成員都有一個合適的初始值,并且在對象的生命周期內只調用一次。
我們可以簡單的理解為,構造函數是所有對象的成員方法中,最早被調用的那個。常用于初始化對象的狀態,例如人的名字、火車的節數等。
和構造函數對應的是析構函數,析構函數是所有對象的成員方法中,最后被調用的那個,常常是對象失去存在價值,用于回收對象資源。
一個對象從創建到回收,總共可以劃分為3個階段,如下圖:
其中,對象創建階段的主要工作由構造函數完成,包括對象的初始化,關系的連接等。執行階段主要是對象功能的調用,用于配合整個項目的執行,通常由普通函數(對象的成員函數)完成。銷毀階段由析構函數接手,用于清除對象占用的內存空間,防止內存泄漏的發生。
相比于其他面向對象語言,JavaScript
對象的構造函數比較特殊,它可以是任何一個普通的函數,而且無需在對象中定義。只有兩個約定:
構造函數的命名通常以大寫開頭;
構造函數智能由new
操作符執行;
例如:
function People(name){ this.name = name;}
以上代碼中的People
函數就可以當作構造函數使用,同時它也是一個普通的函數。對象的this
指針章節,我們介紹過,如果一個普通函數中使用this
,this
的內容取決于調用它的對象(obj.func()
),如果不使用對象調用函數,那么this
在非嚴格模式下就是Window
,嚴格模式下就是undefined
。
通常情況下,直接調用構造函數會得到不正確的結果,如果我們希望把函數當作構造函數調用,就需要使用一個新的關鍵字new
。
以下代碼使用new
關鍵字創建了兩個People
對象:
let xiaoming = new People('xiaoming'); let xiaohong = new People('xiaohong'); console.log(xiaoming.name); console.log(xiaohong.name);
以下是代碼的執行結果:
當使用new
調用一個函數時,這個函數就會變成構造函數,此時,引擎就會執行以下動作:
創建一個新的空對象{ }
,并把空對象賦值給this
;
執行構造函數體,通常會通過this
構造對象的內部結構;
返回this
的值;
你沒有看錯,使用new
調用函數后,函數是有返回值的,即使在定義函數時沒有return
語句。
代碼new People('xiaoming')
所做的事情大概類似以下代碼:
function People(name){ this = {};//隱式的創建一個空對象 this.name = name; return this;//把創建的對象返回}
所以使用new
調用構造函數后,得到的是一個由構造函數塑造過的對象。
使用new
關鍵字的好處是,我們可以書寫一次構造函數代碼,然后在任意的地方創建類似的對象。
例如:
let xiaoming = new People('xiaoming');let xiaohong = new People('xiaohong');let mingming = new People('mingming');
想象一下,如果對象的代碼有上百行,這么做是不是比{...}
方式要簡便很多呢?這就是面向對象中的代碼服用,可以極大程度上降低代碼量,提高開發速度。
如果構造函數沒有參數,我們可以省略調用時的括號:
let xiaoming = new People;//類似于這樣let xiaoming = new People();//等價于這樣但是個人推薦不要使用這種特性,僅僅是告知在規范中存在這種語法。
強調:
從技術上講,任何函數(除了箭頭函數,它沒有自己的
this
)都可以用作構造器。即可以通過new
來運行,它會執行上面的算法。“首字母大寫”是一個共同的約定,以明確表示一個函數將被使用new
來運行。
如果我們只希望對象被創建一次,那么就可以簡化構造函數的定義,使用new
直接調用匿名函數,創建一個對象:
let xiaoming = new function(){ this.name = 'xiaoming';}console.log(xiaoming.name);
代碼的執行結果如下:
使用匿名函數當作構造函數的結果和常規構造函數沒有任何區別,唯一的區別是匿名構造函數不能重復調用(因為沒有名字)。這種使用方法常用在無需復用代碼的場景中。
常規情況下,構造函數不需要使用return
語句,它的唯一用途就是把對象的屬性寫入this
,然后直接默認返回this
對象就好了。
但是,由于JavaScript
對構造函數幾乎沒有任何約束,如果我們在一個普通函數中寫了返回語句,會發生什么呢?引擎會做下面兩個選擇:
如果return
返回的是一個對象,就返回這個對象,不再返回this
;
如果return
返回的是一個基礎類型,則忽略返回語句,繼續返回this
;
從引擎的處理方式中不難看出,構造函數的主要任務就是創建對象,處理并返回,如果使用構造函數返回一個基礎類型,是沒有意義的。
舉個栗子:
function People(name){ this.name = name; return {name:'Nobody'};}console.log(new People('xiaoming').name);
代碼執行結果如下:
可以看出,name
為’xiaoming’的對象沒有被返回,而是Nobody
對象代替了xiaoming
。
如果使用return
返回一個基礎類型,案例如下:
function Dog(){ this.name = 'hashiqi'; return 666;}console.log(new Dog().name);
代碼執行結果如下:
可見,在返回基礎類型時,return
語句是不生效的。
強調:
通常對象的構造函數沒有返回值,我們也沒有必要利用引擎對構造函數返回值的特殊處理,編寫特別的構造函數。
在構造函數中不僅可以添加對象的屬性,由于JavaScript
的函數同樣可以賦值給變量,我們還可以用構造函數初始化對象的成員方法。
例如,我們可以給People
對象增加一個sing
方法:
function People(name){ this.name = name; this.sing = function(){ console.log(`${name} is a happy boy.`); }}let xiaoming = new People('xiaoming');xiaoming.sing();
以上代碼在構造函數中為對象添加了一個方法,代碼執行結果如下:
到此,相信大家對“JavaScript對象的構造函數和new操作符怎么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。