摘要:這也解答了我曾經(jīng)的一個(gè)疑問同樣的道理,在調(diào)用屬性的瞬間,也是使用先來實(shí)例化一個(gè)對象,所以那一瞬間他們的構(gòu)造函數(shù)以及原型對象是相同的,但也僅僅是那一瞬間。
經(jīng)常在國內(nèi)的各大網(wǎng)站博客上看到一句話,叫做JS中萬物皆對象,那是否真是如此?
那么,我們先來捋一捋JS中的數(shù)據(jù)類型,JS中的數(shù)據(jù)類型有下面幾種
Undefined
Null
Boolean
Number
String
Symbol (ES6中新增)
Object
所以本質(zhì)上真的都是Object? -- NO 1.數(shù)據(jù)類型在JS中我們把前面六種類型稱為為基本數(shù)據(jù)類型,最后一種則是復(fù)雜數(shù)據(jù)類型,也就是對象類型。其實(shí)從這里看貌似已經(jīng)區(qū)分了對象以及其他。
2.對象類型與其他類型的區(qū)別對象可以動(dòng)態(tài)的添加屬性和方法,而基本類型不行。
如下:
// 基本類型 Number var num1 = 1000; num1.length = 10; console.log(num1.length); //undefinded // 對象類型 Array var arr1 = []; arr1.length = 10; console.log(arr1.length); //103.值類型與引用類型
再進(jìn)一步看,JS中的數(shù)據(jù)類型有值類型(基本類型)和引用類型(對象類型)之分(其實(shí)其他很多語言中也有這么個(gè)區(qū)別),所謂值類型和引用類型,無非只是實(shí)例對象中保存了值或者保存了對象的引用。
值類型:初始化一個(gè)值類型實(shí)例的時(shí)候,實(shí)際上是給這個(gè)值分配了一個(gè)內(nèi)存空間來保存,當(dāng)進(jìn)行賦值操作的時(shí)候,新的實(shí)例會(huì)開辟一塊新的內(nèi)存空間,然后將原來的值copy 到了這個(gè)新的內(nèi)存空間中;
引用類型:初始化一個(gè)引用類型實(shí)例的時(shí)候,僅僅是把這個(gè)實(shí)例的值所在內(nèi)存空間的引用賦給這個(gè)實(shí)例,當(dāng)copy 給了新的實(shí)例對象使,實(shí)際上是copy 了對這塊內(nèi)存空間的引用,兩個(gè)實(shí)例對象本質(zhì)上共用一塊內(nèi)存空間。
舉個(gè)?:
// 值類型 Number var num1 = 1; var num2 = num1; num2 = num2 + 1 console.log(num1); // 1 // 引用類型 Array var arr1 = []; var arr2 = arr1; arr2.push("oujm") console.log(arr1); // ["oujm"]目前的結(jié)論
其實(shí)從上面看,很明顯的能得出JS中并非萬物皆對象,可為什么還是有這么多的人認(rèn)為并相信這個(gè)觀點(diǎn)是正確的呢?(包括當(dāng)初懵懂無知的我?)
為什么呢? 1. typeof nullconsole.log(typeof null); // object
很多人(可能不多,我瞎猜)都說,連null 都是對象類型,其他的能不是對象嗎?講道理我之前也很疑惑。直到在看書的時(shí)候看到null 只不過是一個(gè)空對象引用,這么說來,它的類型是object 也就沒有那么奇怪了。
2. 基本數(shù)據(jù)類型的實(shí)例對象有 __proto__還有些人說這個(gè)是JS中的一個(gè)bug ,不同的對象在底層都表示為二進(jìn)制,在 JavaScript 中二進(jìn)制前三位都為 0 的話會(huì)被判 斷為 object 類型,null 的二進(jìn)制表示是全 0,自然前三位也是 0,所以執(zhí)行 typeof 時(shí)會(huì)返回"object" 。是真也好,假也罷。但說這是個(gè)bug 其實(shí)沒必要,我不知道底層是怎么實(shí)現(xiàn),可僅僅是因?yàn)?b>null 在底層全是0就返回object ,這種bug 未免顯的太低級了點(diǎn)把... 我更愿意相信,JS的設(shè)計(jì)者就是想把null 表示為空對象引用
如下所示:
var str = "oujm"; console.log(str.__proto__); /* String { anchor:? anchor() at: ? at() big: ? big() blink: ? blink() bold: ? bold() charAt: ? charAt() charCodeAt: ? charCodeAt() codePointAt: ? codePointAt() concat: ? concat() constructor: ? String() ... } */ // Boolean Number 等基本類型打印出來的結(jié)論類似
從我們之前的學(xué)習(xí)中能知道str 是個(gè)基本類型,基本類型怎么會(huì)有屬性呢??墒沁@里不但看到了這個(gè)基本類型的實(shí)例對象有屬性__proto__,而且很明顯它的構(gòu)造函數(shù)就是String() ,這個(gè)時(shí)候有些人就會(huì)覺得既然有屬性,有構(gòu)造函數(shù),那說明str 本質(zhì)上就是個(gè)對象。這在表面上看起來好像是沒什么問題。
那讓我們再來看一個(gè)更直白的?:
var str1 = "oujm"; var str2 = str1.substring(2);
從上面能看出來str1 是有方法的。
OK,宗上所得:基本類型也是對象類型,即萬物皆對象
我覺得大部分人能得出這個(gè)結(jié)論都基于此。但是他們忽略了,在JS的世界中有一種對象類型叫包裝對象。
咦?,String ,Number ,Boolean ,這三個(gè)不是基本類型嗎。其實(shí)不然,ECMAScript提供了這三個(gè)特殊的引用類型,這三個(gè)引用類型和其他的引用類型相似,但同時(shí)也具有于各自的基本類型相應(yīng)的特殊行為,實(shí)際上,每當(dāng)讀取一個(gè)基本類型的時(shí)候,后臺(tái)就會(huì)創(chuàng)建一個(gè)對應(yīng)的基本包裝類型的對象。
再來看上面那個(gè)?,str1 很明顯是一個(gè)基本類型實(shí)例,問題就出在 str1.substring(2) 字符串怎么會(huì)有方法。其實(shí),為了讓我們更好的操作基本類型的實(shí)例對象,后臺(tái)進(jìn)行了一系列的操作:
創(chuàng)建String的實(shí)例
在實(shí)例上調(diào)用指定的方法
銷毀這個(gè)實(shí)例
// var str2 = str1.substring(2) 動(dòng)作拆解: var tempStr = new String("oujm"); var str2 = tempStr.substring(2); tempStr = null;
從這里能夠看到,一般的引用類型和包裝類型唯一的區(qū)別就在于對象的生命周期。包裝類型的對象生命周期很短,只有代碼執(zhí)行的一瞬間,然后就被銷毀了,所以這也就是為什么我們不能在運(yùn)行的時(shí)候?yàn)榛绢愋偷闹堤砑訉傩院头椒ā?/p>
var str1 = "oujm"; var str1.bf = "ethan"; console.log(str1.bf); // undefined
這也解答了我曾經(jīng)的一個(gè)疑問
var str1 = "oujm"; var str2 = new String("ethan"); console.log(str1.__proto__ === str2.__proto__); // true console.log(str1 instanceof String); // false console.log(str2 instanceof String); // true
同樣的道理,在調(diào)用__proto__ 屬性的瞬間,也是使用new String() 先來實(shí)例化一個(gè)對象,所以那一瞬間他們的構(gòu)造函數(shù)以及原型對象是相同的,但也僅僅是那一瞬間。
綜上別再?到有些文章說的,JS的世界很大,并不只有對象
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/89826.html
摘要:原型鏈理解第一件事你不用管其他語言,一句話,你只要記住里面的對象包含一個(gè)原型,原型是啥,就是另外一個(gè)對象。原型就相當(dāng)于你家的車棚子,而你的那個(gè)自行車就是對象。萬事萬物皆對象有啥用一句話,擴(kuò)展原型方法,給大家一到面試題,數(shù)組去重自己體會(huì)下。 概述 通過上節(jié)課的學(xué)習(xí),大家已經(jīng)會(huì)用一種json的方式定義對象了,其實(shí)這個(gè)就是傳說中的單體模式,當(dāng)然這個(gè)大家不用記,關(guān)于設(shè)計(jì)模式暫時(shí)不用了解。但是總...
摘要:真正的前方高能第一個(gè)鋪墊告訴我們,對象可以映射成布爾值真假,第二個(gè)鋪墊告訴我們,布爾值可以映射成數(shù)字和。得知布爾值和有這一層隱秘的身份,我已興奮不已,再難對這看似不合現(xiàn)代語境卻又流傳千古的思想做出任何揣測。 這么久以來,我終于確認(rèn)了一件事,那就是不管是人也好,還是貓也好,常常會(huì)忘了想自己當(dāng)下的身份位置,以及曾經(jīng)的身份位置。 這個(gè)現(xiàn)象在我身上,表現(xiàn)出了雙倍分量的嚴(yán)重。這種時(shí)刻,我就會(huì)想起...
摘要:真正的前方高能第一個(gè)鋪墊告訴我們,對象可以映射成布爾值真假,第二個(gè)鋪墊告訴我們,布爾值可以映射成數(shù)字和。得知布爾值和有這一層隱秘的身份,我已興奮不已,再難對這看似不合現(xiàn)代語境卻又流傳千古的思想做出任何揣測。 這么久以來,我終于確認(rèn)了一件事,那就是不管是人也好,還是貓也好,常常會(huì)忘了想自己當(dāng)下的身份位置,以及曾經(jīng)的身份位置。 這個(gè)現(xiàn)象在我身上,表現(xiàn)出了雙倍分量的嚴(yán)重。這種時(shí)刻,我就會(huì)想起...
摘要:深入之繼承的多種方式和優(yōu)缺點(diǎn)深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點(diǎn) JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎,再讓我...
閱讀 3178·2021-09-27 13:35
閱讀 724·2021-09-23 11:22
閱讀 2986·2019-08-30 15:54
閱讀 1727·2019-08-29 16:27
閱讀 2563·2019-08-29 15:05
閱讀 2444·2019-08-23 18:11
閱讀 3606·2019-08-23 16:32
閱讀 3015·2019-08-23 14:56