摘要:關(guān)于操作符,我的理解一里有進(jìn)一步描述舉例即是構(gòu)造函數(shù)在本例中,對(duì)象具有特定的類型,可稱之為一個(gè)對(duì)象。用作對(duì)象類型的標(biāo)記使用構(gòu)造函數(shù)創(chuàng)建的對(duì)象可以很方便的檢查它們的類型,比如為對(duì)象創(chuàng)建共享屬性這可能是使用構(gòu)造函數(shù)最重要的理由了。
JavaScript 中的構(gòu)造器 什么是構(gòu)造器?
構(gòu)造器也叫構(gòu)造函數(shù),它就是一個(gè)普通的函數(shù),只不過它的主要目的是用于和 new 操作符配合來創(chuàng)建特定類型的對(duì)象。(關(guān)于 new 操作符,我的理解 JavaScript(一)里有進(jìn)一步描述)
舉例:
var me = new Person("Albert", "Yu", 32); // Person 即是構(gòu)造函數(shù)
在本例中,me 對(duì)象具有特定的類型,可稱之為:一個(gè) Person 對(duì)象。而 Person 就是它的類型名字。
那么構(gòu)造函數(shù)內(nèi)部又是如何工作的?
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; };
和普通的函數(shù)相比,有兩個(gè)明顯的區(qū)別,解釋如下:
函數(shù)名稱首字母大寫:這其實(shí)只是一個(gè)約定而不是強(qiáng)制行為,絕大多數(shù) JavaScript 程序員都會(huì)遵守這個(gè)約定,即首字母大寫的函數(shù)名是一個(gè)構(gòu)造函數(shù);當(dāng)然,首字母小寫的函數(shù)一樣可以充當(dāng)構(gòu)造函數(shù)
使用 this 捆綁局部變量:一般性的函數(shù)都是直接創(chuàng)建本地變量來保存值,而構(gòu)造函數(shù)使用 this 捆綁局部變量是為了配合 new 操作符。因?yàn)?new 操作符會(huì)創(chuàng)建一個(gè)新對(duì)象,并且把新對(duì)象綁定在構(gòu)造函數(shù)內(nèi)部的 this 上,于是被捆綁在 this 上的局部變量事實(shí)上就成為新對(duì)象的屬性了
因此,這樣的構(gòu)造函數(shù)所創(chuàng)建的對(duì)象大致等價(jià)于:
var me = { firstName: "Albert", lastName: "Yu", age: 32 };
那么既然如此,我們?yōu)樯哆€要寫構(gòu)造函數(shù)?
構(gòu)造函數(shù)的用處 1. 用作創(chuàng)建對(duì)象的模板如果只需要?jiǎng)?chuàng)建少量對(duì)象(比如一個(gè)),編寫構(gòu)造函數(shù)的確沒太大意義。但是遇到需要重復(fù)創(chuàng)建對(duì)象的場(chǎng)合,構(gòu)造函數(shù)顯然是 DRY(Don"t Repeat Youself)的上佳選擇。
不僅僅是為了減少重復(fù)編碼的工作量,而且經(jīng)常會(huì)有對(duì)于輸入?yún)?shù)進(jìn)行驗(yàn)證并拋出錯(cuò)誤的功能設(shè)計(jì),也可以借助構(gòu)造函數(shù)來完成。
2. 用作對(duì)象類型的標(biāo)記使用構(gòu)造函數(shù)創(chuàng)建的對(duì)象可以很方便的檢查它們的類型,比如:
var me = new Person("Albert", "Yu", 32); var you = { firstName: "Super", lastName: "Man", age: 18 }; console.log(me instanceof Person); // true console.log(you instanceof Person); // false3. 為對(duì)象創(chuàng)建共享屬性
這可能是使用構(gòu)造函數(shù)最重要的理由了。基于原型繼承的 JavaScript 可以很方便的為對(duì)象擴(kuò)充成員屬性:
var me = new Person("Albert", "Yu", 32); me.firstName; // "Albert" me.lastName; // "Yu" me.age; // 32 // 我想要標(biāo)記所有的 Person 對(duì)象都是活著的…… Person.prototype.isAlive = true; me.isAlive; // true // 我還想要輸出用戶的全名…… me.firstName + " " + me.lastName; // "Albert Yu" // 這樣太二了吧? Person.prototype.fullName = function() { return [this.firstName, this.lastName].join(" "); }; me.fullName(); // "Albert Yu" // 嗯,文藝多了……
有一點(diǎn)特別需要注意的!
使用構(gòu)造函數(shù)創(chuàng)建對(duì)象一定要使用 new 操作符
這是因?yàn)椋ㄔ俅螐?qiáng)調(diào)):真正創(chuàng)建新對(duì)象的不是構(gòu)造函數(shù),而是 new 操作符。構(gòu)造函數(shù)只是充當(dāng)新對(duì)象的模板,它接收 new 創(chuàng)建的對(duì)象然后用模板填充這個(gè)對(duì)象的屬性設(shè)置。
鑒于此,忘記使用 new 的話是比較危險(xiǎn)的。因?yàn)闆]有 new 創(chuàng)建新對(duì)象的時(shí)候,構(gòu)造函數(shù)內(nèi)的 this 會(huì)被捆綁給全局對(duì)象,通常是 window(瀏覽器)或者 global(Node.js),讓我們看看會(huì)發(fā)生啥事兒吧……
var me = new Person("Albert", "Yu", 32); me.firstName; // "Albert" var you = Person("Super", "Man", 18); you.firstName; // undefined... WTF?! this.firstName; // "Super"...Shiiiit! // 上面的 this 是全局對(duì)象
那么如何改進(jìn)構(gòu)造函數(shù)呢?簡單。
function Person(firstName, lastName, age) { if (this instanceof Person) { // 想一想還有沒有其他的判斷方式? this.firstName = firstName; this.lastName = lastName; this.age = age; } else { throw new Error("不用 `new` 是不可以的喲~~~"); } }
這個(gè)思路就是先判斷構(gòu)造函數(shù)接收到的 this 是不是自己的實(shí)例,若是則一切好說,若不是則拋出錯(cuò)誤強(qiáng)制用戶使用 new 操作符。
當(dāng)然,這個(gè)改進(jìn)雖然可靠了,但還是不夠“聰明”,要是能讓構(gòu)造函數(shù)自己判斷來自動(dòng)使用 new 該多好呀!沒錯(cuò),這是更好地方式,不過在這里我就不演示了,還是由您自己來動(dòng)手實(shí)踐一下吧?(提示:考慮一下構(gòu)造函數(shù)的原型對(duì)象。如果想不出來的話不要緊,我們以后接著聊)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77965.html
摘要:第四點(diǎn)也要著重講下,記住構(gòu)造函數(shù)被操作,要讓正常作用最好不能在構(gòu)造函數(shù)里 4) this、new、call和apply的相關(guān)問題 講解this指針的原理是個(gè)很復(fù)雜的問題,如果我們從javascript里this的實(shí)現(xiàn)機(jī)制來說明this,很多朋友可能會(huì)越來越糊涂,因此本篇打算換一個(gè)思路從應(yīng)用的角度來講解this指針,從這個(gè)角度理解this指針更加有現(xiàn)實(shí)意義。 下面我們看看在ja...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
閱讀 938·2021-11-22 13:53
閱讀 2561·2021-10-15 09:40
閱讀 1044·2021-10-14 09:42
閱讀 3679·2021-09-22 15:59
閱讀 924·2021-09-02 09:47
閱讀 2464·2019-08-30 15:54
閱讀 1473·2019-08-29 17:14
閱讀 432·2019-08-29 15:15