{…}語法允許建立一個對象,但如果需要建立多個類似的對象,則我們需要使用建構函式和“new”操作符。
建構子技術上就是正常的函數,但一般有兩個約定:
1、他們的名稱第一個字母大寫。
2、他們應該只使用new操作符執行。
範例:
function User(name) { this.name = name; this.isAdmin = false; } let user = new User("Jack"); alert(user.name); // Jack alert(user.isAdmin); // false
我們來看執行new User()
時背後到底做了什麼?
1、先建立一個空對象,然後賦值給this。
2、執行函數,通常修改this對象,增加一些新的屬性。
3、this被回傳。
換句話說,new User()
內容如下程式碼所示:
function User(name) { // this = {}; (implicitly) // we add properties to this this.name = name; this.isAdmin = false; // return this; (implicitly) }
所以new User("Jack")
的結果和下面程式碼一致:
let user = { name: "Jack", isAdmin: false };
現在我們想要建立其他對象,我們可以使用new User("Ann")
,new User("Alice")
等。比每次使用文字描述物件方式更簡短,且易讀。
這時建構函數的主要目的——————實現創建物件的程式碼重用。
讓我們再次注意:
技術上,任何函數都可以用作構造器,即任何函數都可以使用new調用,並且也執行上面描述的演算法。
首字母大寫只是一個常規約定,使其更清晰說明其為構造韓式,應該使用new調用。
new function(){…}
如果我們有多行程式碼,用於建立一個複雜對象,我們可以包裝他們使用建構函數,程式碼如下:
let user = new function() { this.name = “John”; this.isAdmin = false; // ...other code for user creation // maybe complex logic and statements // local variables etc };
該建構器不能再次調用,因為沒有被保存,僅僅被調用創建物件。這個技巧的母的只是為了封裝單一複雜物件程式碼。
函數內部,我們可以檢查其呼叫方式是否使用new方式。使用一個特殊的屬性new.target
可以。
普通呼叫其值為空,透過new呼叫其值為該函數。
function User() { alert(new.target); } User(); // undefined new User(); // function User { ... }
下面程式碼可以實現使用常規方式和new操作方式效果一致。
function User(name) { if (!new.target) { // if you run me without new return new User(name); // ...I will add new for you } this.name = name; } let john = User("John"); // redirects call to new User alert(john.name); // John
這個方法在一些函式庫中使用,為了讓程式碼更有彈性。但到處使用並非好事,對熟悉User物件內部狀況不夠明顯。
通常建構器無需傳回值語句。它的任務是往this物件中寫一些必要內容,然後自動返回之。
但如果有return語句,那麼規則很簡單:
- 如果return返回一個對象,那麼則代替this被返回。
- 如果return回傳原始類型,則被忽略,仍然傳回this。
也就是說,return要麼返回對象,要麼返回this,下面示例代替this返回對象,示例如下:
function BigUser() { this.name = "John"; return { name: "Godzilla" }; // <-- returns an object } alert( new BigUser().name ); // Godzilla, got that object
這個示例return空,或者在寫原始類型,其實都不影響。
function SmallUser() { this.name = "John"; return; // finishes the execution, returns this // ... } alert( new SmallUser().name ); // John
大多數建構子不需要返回,這裡提醒這種特殊行為,只是為了知識完整性。
忽略括號
順便說下,呼叫建構子是,如果沒有參數,我們可以省略物件標識後面的括號。
let user = new User; // <-- no brackets // same as let user = new User();
忽略括號並不是一個好的程式碼風格,但規範中是允許的。
使用建構子建立物件提供了很大的靈活性,提供參數可以定義不同的物件。
當然,我們不只為this增加屬性,也可以增加方法。
下面範例建立對象,使用name參數,並增加一個方法sayHi:
function User(name) { this.name = name; this.sayHi = function() { alert( "My name is: " + this.name ); }; } let john = new User("John"); john.sayHi(); // My name is: John /* john = { name: "John", sayHi: function() { ... } } */
建構子或簡稱建構器,是普通函數,但有一般約定,名稱第一個字母大寫。
建構子使用new調用,也就是開始建立一個空this對象,然後傳回填滿內容的this。
我們能使用建構子建立多個類似對象,當日內容不只這些,後面進一步說明。
Javascript為一些內建物件提供了建構函數,如日期的Date,集合Set等。
以上是JavaScript中建構函數與new運算子的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!