一文帶你深入理解JavaScript對(duì)象與包裝類(lèi)
對(duì)象的創(chuàng)建方式
- 對(duì)象字面量:最直接的方式,通過(guò)鍵值對(duì)的形式定義對(duì)象。
var mrPeng = {
name: '彭于晏',
age: 18,
sex: 'boy',
};
new Object():構(gòu)造函數(shù)方式創(chuàng)建一個(gè)空對(duì)象。
var obj = new Object();
- 自定義構(gòu)造函數(shù):通過(guò)
new關(guān)鍵字調(diào)用自定義的構(gòu)造函數(shù)來(lái)創(chuàng)建特定類(lèi)型的對(duì)象。
function Car(name, height) {
this.name = name;
this.height = height;
}
var car = new Car('Toyota', 1500);
- 模擬構(gòu)造函數(shù):模擬一個(gè)構(gòu)造函數(shù),但不使用
new關(guān)鍵字,需手動(dòng)實(shí)現(xiàn)。
function Person(name, age){
var self = {};
self.name = name;
self.age = age;
return self;
}
let p = Person('Alice', 30);
包裝類(lèi)
進(jìn)度一
先來(lái)看看這段JS代碼:
var num = 123; num.a = 'aaa'; console.log(num.a); // undefined
簡(jiǎn)單解釋一下代碼:代碼中先聲明了一個(gè)Num,并賦值為123,再在Num上掛上一個(gè)屬性a,其值為字符串aaa,然后打印輸出Num中a的值
如果你也是這樣想的話,那么你心中輸出的結(jié)果不就是字符串aaa嘛。可是輸出的結(jié)果真的是字符串aaa嗎???
當(dāng)然不是,我可以清楚的告訴你,該段代碼輸出的是undefined。說(shuō)明屬性a并沒(méi)有掛在num上,畢竟num不是對(duì)象,那竟然沒(méi)掛上去,訪問(wèn)不存在的東西時(shí),不應(yīng)該報(bào)錯(cuò)嗎?那又為什么輸出的是undefined呢?
首先,我們通過(guò)該段代碼能知道:在JS中原始值(原始類(lèi)型數(shù)據(jù))(如數(shù)字
Number、字符串String、布爾值boolean等)不能擁有屬性和方法,屬性和方法只有對(duì)象才能擁有。
那么如果我們將var num = 123;改寫(xiě)成var num = new Number(123);呢,我們就得到了一個(gè)對(duì)象,可是對(duì)象里面沒(méi)有key,只有一個(gè)值為123。展開(kāi)Number(123)這個(gè)對(duì)象看一下,就會(huì)看到有一個(gè)[[PrimitiveValue]]:123,意思就是說(shuō)這是一種特殊的對(duì)象Number(123),這個(gè)對(duì)象就是我們說(shuō)的包裝類(lèi)。

你說(shuō)他是對(duì)象他就是對(duì)象,你說(shuō)他是數(shù)字他也是數(shù)字,他能當(dāng)成數(shù)字來(lái)用。
var num = new Number(123); console.log(num*2);// 輸出246 num.a = 'aaa'; console.log(num.a); //輸出aaa
這就說(shuō)明當(dāng)你將他用來(lái)當(dāng)對(duì)象,他就是對(duì)象,用來(lái)當(dāng)數(shù)字,他就是數(shù)字。
var num = 123;這種創(chuàng)建的叫數(shù)字字面量,而var num = new Number(123);創(chuàng)建的叫Number對(duì)象(數(shù)字對(duì)象)。對(duì)象是可以有屬性和方法的,而原始值是沒(méi)有的。
進(jìn)度二
讓我們來(lái)看看先這段代碼:
var str ='asdf' console.log(str.length) //輸出4
為什么這個(gè)能輸出4呢?總不能說(shuō)剛剛得到的結(jié)論是錯(cuò)的吧
在解決上面這個(gè)問(wèn)題前先來(lái)看看這段代碼:
var num = 4; num.len = 3; // console.log(num.len); // undefined
根據(jù)上面的結(jié)論,我們能知道這里的 len是不能掛在原始值上的,輸出的肯定是undefined,沒(méi)錯(cuò)吧。
我們來(lái)解析一下上面那段代碼,看看在v8引擎是怎樣實(shí)現(xiàn)的:
- 首先,在執(zhí)行
var num = 4;時(shí) ,v8會(huì)將代碼執(zhí)行為new Number(4),也就是所有的字面量都會(huì)執(zhí)行成這個(gè)樣子,包括字符串和布爾會(huì)執(zhí)行成new String()和new Boolean(),將其轉(zhuǎn)換為對(duì)象,也就是包裝類(lèi)。 - 然后,v8在執(zhí)行這個(gè)代碼
num.len = 3;時(shí),就會(huì)將len屬性掛在Number這個(gè)對(duì)象上,且值為3。因?yàn)樵贘S中數(shù)字對(duì)象就是為了彌補(bǔ)數(shù)字字面量的不足,在JS中萬(wàn)物皆對(duì)象,所有的東西都要往對(duì)象上靠 - 最后,在執(zhí)行
console.log(num.len);之前就會(huì)突然醒悟過(guò)來(lái),也就是在讀取該值或在執(zhí)行前會(huì)使用 str.valueof()方法 ,判斷這個(gè)對(duì)象(數(shù)字對(duì)象)是否能轉(zhuǎn)化為原始值(str.valueof()方法只能操作包裝類(lèi)),如果能轉(zhuǎn)化為原始值,那么就會(huì)將屬性和方法移除,執(zhí)行delete num.len。然而在輸出的時(shí)候,num.len先在Number對(duì)象中查找,找不到就會(huì)聲明一個(gè)len屬性再對(duì)象中,但是沒(méi)有值啊,所以輸出的就是undefined,而不不是報(bào)錯(cuò)?。。?/li>
訪問(wèn)對(duì)象不存在的屬性,會(huì)返回undefined
訪問(wèn)不存在的不變量,會(huì)報(bào)錯(cuò)??!
那么現(xiàn)在我們來(lái)解決上面那個(gè)問(wèn)題:
var str ='asdf' console.log(str.length) //輸出4
- 首先,一樣的,在執(zhí)行
var str ='asdf'時(shí),v8會(huì)執(zhí)行為var str =new String('asdfg')包裝類(lèi) - 然后,str調(diào)用length方法,并且輸出,他沒(méi)有往原始值上掛屬性,直接調(diào)用的話,會(huì)去對(duì)象(包裝類(lèi))中查找該方法,找不到該方法就會(huì)去,該對(duì)象的原型上找,也就是我們之前提到的,按照他的原型鏈去查找該方法,而String這個(gè)構(gòu)造函數(shù)中是有該方法的,可以直接調(diào)用。
總結(jié)
包裝類(lèi)(
String,Number,Boolean)是JavaScript為原始值提供的對(duì)象包裝器,允許我們像操作對(duì)象一樣操作原始值,包括訪問(wèn)屬性和方法,只不過(guò)屬性和方法并不是原始值身上的,而是String,Number,Boolean的構(gòu)造函數(shù)(對(duì)象)上的。原始值是不能擁有屬性和方法,屬性和方法只有對(duì)象才能擁有
重要特性:每當(dāng)試圖訪問(wèn)原始值的屬性或方法時(shí),JavaScript會(huì)自動(dòng)創(chuàng)建包裝類(lèi),執(zhí)行完畢后立即銷(xiāo)毀,確保原始值的不變性。這就是為什么直接給原始值添加屬性沒(méi)有效果的原因。
valueOf():為了使valueOf在類(lèi)型轉(zhuǎn)換過(guò)程中有用,它必須返回一個(gè)原始值(基本類(lèi)型值)。所有的原始類(lèi)型(基本類(lèi)型)都有自己的valueOf()方法。JavaScript 調(diào)用valueOf方法來(lái)將對(duì)象轉(zhuǎn)換成原始值(基本類(lèi)型值)。你很少需要自己調(diào)用valueOf方法;當(dāng)遇到需要基本類(lèi)型值的對(duì)象時(shí),JavaScript 會(huì)自動(dòng)的調(diào)用該方法。原始值對(duì)象,v8 執(zhí)行到包裝類(lèi)時(shí),會(huì)通過(guò)
valueOf()試探該包裝類(lèi)是不是原始值,如果是,則秉承原始值不用具有屬性和方法的這一規(guī)則,再移除掉給包裝類(lèi)添加的屬性
以上就是深入理解JavaScript對(duì)象與包裝類(lèi)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript對(duì)象與包裝類(lèi)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript中最常見(jiàn)的三個(gè)面試題解析
JavaScript是所有現(xiàn)代瀏覽器的官方語(yǔ)言。 因此,JavaScript 問(wèn)題出現(xiàn)在各種開(kāi)發(fā)人員的面試中。這篇文章主要跟大家分享了關(guān)于JavaScript中最常見(jiàn)的三個(gè)面試題,需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。2017-03-03
js優(yōu)化針對(duì)IE6.0起作用(詳細(xì)整理)
js優(yōu)化針對(duì)IE6.0起作用,總結(jié)一下幾點(diǎn):字符串拼接、for 循環(huán)、減少頁(yè)面的重繪、減少作用域鏈上的查找次數(shù)、避免雙重解釋等等,需要了解的朋友可以參考下,或許會(huì)有所幫助2012-12-12
使用webpack將ES6轉(zhuǎn)化ES5的實(shí)現(xiàn)方法
這篇文章主要介紹了使用webpack將ES6轉(zhuǎn)化ES5的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
鍵盤(pán)上一張下一張兼容IE/google/firefox等瀏覽器
鍵盤(pán)上一張下一張的效果想必大家都有見(jiàn)到過(guò)吧,本文為大家介紹的這個(gè)兼容IE,google,firefox等主流瀏覽器2014-01-01
javascript支持firefox,ie7頁(yè)面布局拖拽效果代碼
javascript 拖拽 頁(yè)面拖拽 拖拽效果的頁(yè)面 超級(jí)拖拽 javascript支持firefox,ie7頁(yè)面布局拖拽效果代碼 鼠標(biāo)拖拽2007-12-12
淺析Javascript中bind()方法的使用與實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇淺析Javascript中bind()方法的使用與實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,一起跟隨小編過(guò)來(lái)看看吧2016-04-04
HTML頁(yè)面滾動(dòng)時(shí)獲取離頁(yè)面頂部的距離2種實(shí)現(xiàn)方法
獲取離滾動(dòng)頁(yè)面的頂部距離有兩種方法一是DOM;而是jquery,具體的實(shí)現(xiàn)如下,感興趣的朋友可以嘗試操作下2013-09-09
TypeScript 不可變性 readonly, Readonly<T>的使用小結(jié)
TypeScript 作為 JavaScript 的超集,為我們提供了強(qiáng)大的類(lèi)型系統(tǒng),其中就包括了實(shí)現(xiàn)不可變性的有效工具,今天,我們就來(lái)聊聊如何使用 readonly和 Readonly來(lái)提升代碼的健壯性和可維護(hù)性2026-05-05

