摘要:首先,我先去上搜索了的定義運算符創(chuàng)建一個用戶定義的對象類型的實例或具有構(gòu)造函數(shù)的內(nèi)置對象的實例。
今天看到一道面試題,如下,問: 實例化 Person 過程中,Person返回什么(或者 p 等于什么)?
function Person(name) { this.name = name return name; } let p = new Person("Tom");
說實話,第一反應(yīng)我以為值為 "Tom",等到我把代碼丟到控制臺一輸出,才明白我錯了。天吶,new運算符給無視掉了嗎???
撇開 new 的存在,我們修改下代碼
function Person(name) { this.name = name return name; } let p = Person("Tom"); console.log(p);
很顯然,輸出的結(jié)果是 "Tom", 但是有 new 存在呢?接下去,我們來捋一捋。
首先,我先去 MDN上搜索了 new 的定義
new 運算符創(chuàng)建一個用戶定義的對象類型的實例或具有構(gòu)造函數(shù)的內(nèi)置對象的實例。
emmmm,相當(dāng)晦澀難懂。
那我們試著寫幾個栗子看看結(jié)果吧
function Person1(name) { this.name = name; // 沒有返回值 } function Person2(name) { this.name = name; return name; // 返回非對象 } function Person3(name) { this.name = name; return { a: 1 }; // 返回對象 } function Person4(name) { this.name = name; return null; // 返回null } var p1 = new Person1("aa"); var p2 = new Person2("bb"); var p3 = new Person3("cc"); var p4 = new Person4("dd"); console.log(p1); // Person1?{name: "aa"} console.log(p2); // Person2?{name: "bb"} console.log(p3); // {a: 1} console.log(p4); // Person4?{name: "dd"}
根據(jù)上面幾個栗子,我們能得出結(jié)論:當(dāng)使用 new 來創(chuàng)建對象||調(diào)用構(gòu)造函數(shù)時,如果函數(shù)沒有返回值|| 返回值是非對象,那么返回的就是構(gòu)造函數(shù)實例后的對象;如果函數(shù)return對象,那么返回這個對象(特例:return null,返回的也是構(gòu)造函數(shù)實例后的對象而非null)
我們接著看 MDN 文檔的解釋,畢竟光光看這幾個demo沒有說服力。
一起來理解下 new 到底做了什么工作吧~
就拿下面這個 demo分析
function Person(name) { this.name = name; return {a: 1} } var p = new Person("fefeng")
當(dāng)調(diào)用 new Person(...)時,會進行以下幾步:
首先是 繼承自 Person.prototype的新對象會被創(chuàng)建
使用參數(shù) "fefeng" 調(diào)用構(gòu)造函數(shù) Person, 并將 this 綁定到新創(chuàng)建的對象
由 Person 返回的對象就是 new 表達式的結(jié)果 =》 Person 返回的對象是 {a: 1} 所以new 表達式的結(jié)果為 {a:1} ; 如果 Person 沒有返回值(一般構(gòu)造函數(shù)都不返回值)那么使用步驟1創(chuàng)建的對象,即==》 繼承自 Person.prototype 的新對象
貌似照著文檔能夠些許理解了,倘若模擬實現(xiàn) new運算符更能深入理解 new
以下是 new 的模擬實現(xiàn),代碼來源 : JavaScript深入之new的模擬實現(xiàn)
function objectFactory() { var obj = new Object(), cons = [].shift.call(arguments) obj.__proto__ = cons.prototype var ret = cons.apply(obj, arguments) return typeof ret === "object" ? ret|| obj : obj } function Person(name) { this.name = name; return {a: 1} } var p = objectFactory(Person, "fefeng")
當(dāng)然了,學(xué)習(xí)別人的代碼不能僅僅只是照搬過來,起碼得理解這個代碼吧。
使用
首先是創(chuàng)建一個對象,
cons 是調(diào)用 objectFactory 方法的第一個參數(shù),即構(gòu)造函數(shù); 因為 shift 會改變原數(shù)組,所以改變后的 argument 即為調(diào)用構(gòu)造函數(shù)的參數(shù) (這里補充說明下: arguments 是一個對應(yīng)于傳遞給函數(shù)的參數(shù)的類數(shù)組對象。)
將 obj 的原型指向構(gòu)造函數(shù), 這樣 obj 就能訪問到構(gòu)造函數(shù)原型上的屬性
將構(gòu)造函數(shù) cons 的 this 指向 obj,這樣 obj 能訪問構(gòu)造函數(shù)里的屬性
判斷返回的值是不是一個對象,如果是對象即返回它(當(dāng)然這里要處理 return null 的特例);如果不是對象就返回 obj (注意:這里的 obj 已經(jīng)不是一個空對象)
如果你耐心看到了這里,那么十分感謝。如文章有錯誤,望給予指正~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100230.html
摘要:直接開始題目是厲害了說句實話開發(fā)中誰寫成這樣保證會被打死。不過面試就是面試,有面試官的考量點。官方是這么說的。結(jié)果完美,不過小姐姐的意思是數(shù)組的方法會自動觸發(fā)數(shù)組的。 直接開始題目是 if(a==1 && a==2 && a==3){ alert(厲害了) } 說句實話開發(fā)中誰寫成這樣保證會被打死。 不過面試就是面試,有面試官的考量點。 我理解的點有兩個 1、隱式類型轉(zhuǎn)換 先說...
摘要:想必面試題刷的多的同學(xué)對下面這道題目不陌生,能夠立即回答出輸出個,可是你真的懂為什么嗎為什么是輸出為什么是輸出個這兩個問題在我腦邊縈繞。同步任務(wù)都好理解,一個執(zhí)行完執(zhí)行下一個。本文只是我對這道面試題的一點思考,有誤的地方望批評指正。 想必面試題刷的多的同學(xué)對下面這道題目不陌生,能夠立即回答出輸出10個10,可是你真的懂為什么嗎?為什么是輸出10?為什么是輸出10個10?這兩個問題在我腦...
摘要:下面我們來使用面向?qū)ο箢悎D這里就不再畫了首先面試題中所提到的我們都可以看成類,比如停車場是一個類吧,它里面的車位是一個類吧,攝像頭,屏幕。。。 以下是某場的一道面試題(大概): 1、一個停車場,車輛入場時,攝像頭記錄下車輛信息2、屏幕上顯示所接收的車輛的信息情況(車牌號)以及各層車位的車位余量3、停車場一共四層車位,其中的三層都為普通車位,還有一層為特殊車位(體現(xiàn)在停車計費價格上面的不...
摘要:下面我們來使用面向?qū)ο箢悎D這里就不再畫了首先面試題中所提到的我們都可以看成類,比如停車場是一個類吧,它里面的車位是一個類吧,攝像頭,屏幕。。。 以下是某場的一道面試題(大概): 1、一個停車場,車輛入場時,攝像頭記錄下車輛信息2、屏幕上顯示所接收的車輛的信息情況(車牌號)以及各層車位的車位余量3、停車場一共四層車位,其中的三層都為普通車位,還有一層為特殊車位(體現(xiàn)在停車計費價格上面的不...
閱讀 1910·2021-11-25 09:43
閱讀 1557·2021-09-02 15:21
閱讀 3523·2019-08-30 15:52
閱讀 1559·2019-08-30 12:48
閱讀 1374·2019-08-30 10:57
閱讀 2991·2019-08-26 17:41
閱讀 742·2019-08-26 11:59
閱讀 1427·2019-08-26 10:41