摘要:目錄基本類型和引用類型檢測數(shù)據(jù)類型的方法數(shù)據(jù)類型的轉(zhuǎn)換通用庫的初步創(chuàng)建與對象的深淺拷貝小結(jié)從前面三篇文章,我們已經(jīng)大致了解的基本語法中的數(shù)據(jù)類型數(shù)值型字符串布爾型對象數(shù)組函數(shù)和這篇文章將深入探討這幾種數(shù)據(jù)類型在內(nèi)存中的存儲(chǔ)方式讀取方式和拷貝
目錄 1. 基本類型和引用類型 2. 檢測數(shù)據(jù)類型的方法 3. 數(shù)據(jù)類型的轉(zhuǎn)換 4. 通用庫的初步創(chuàng)建與對象的深淺拷貝 5. 小結(jié)
從前面三篇文章,我們已經(jīng)大致了解JavaScript的基本語法中的數(shù)據(jù)類型——數(shù)值型、字符串、布爾型、對象、數(shù)組、函數(shù)、null和undefined;
這篇文章將深入探討這幾種數(shù)據(jù)類型在內(nèi)存中的存儲(chǔ)方式、讀取方式和拷貝方式;
在之前的文章,我們了解到JavaScript中的變量根據(jù)數(shù)據(jù)的復(fù)雜程度可分為原始數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型;
現(xiàn)在,我們將從數(shù)據(jù)內(nèi)存存儲(chǔ)角度,將變量劃分為基本類型值和引用類型值;
基本類型值:保存在棧內(nèi)存的簡單數(shù)據(jù)段,包括數(shù)值、字符串、布爾值、null和undefined;
基本類型值在賦值時(shí),直接將值賦給變量,訪問變量即訪問值,可以直接操作保存在變量的值;
在進(jìn)行基本類型值拷貝時(shí),會(huì)在變量對象上創(chuàng)建一個(gè)新值,然后把值賦給另一個(gè)變量;因此,在改變上述代碼中給a賦b的值后,再改變a的值,將不影響b的值,兩個(gè)變量的獨(dú)立的;
引用類型值:保存在堆內(nèi)存中的對象,變量保存的是一個(gè)指向內(nèi)存中對象的指針;
引用類型在賦值時(shí)是將保存在堆內(nèi)存的對象的地址賦給變量,訪問變量實(shí)際訪問的是變量的指針,該指針指向?qū)ο?,在讀寫(增刪改)操作時(shí)操作的是實(shí)際的對象,但在拷貝時(shí)則是指針;
所有由上述代碼可知:在把a(bǔ)賦值給b時(shí)實(shí)際拷貝的是a的指針,當(dāng)改變對象的屬性值時(shí),a賦予的對象的屬性值也會(huì)改變,因?yàn)槎咧赶蛲粚ο螅?br>但有時(shí)候,我們希望實(shí)現(xiàn)對象的真正拷貝并且切斷引用同一對象的聯(lián)系,具體做法將會(huì)在下文具體講解;
要想實(shí)現(xiàn)對象的深拷貝,第一步首先要知道數(shù)據(jù)的類型,不然后續(xù)工作將無從下手;
JavaScript中提供檢測數(shù)據(jù)類型的方法大致有3種:
typeof操作符
typeof操作符能夠很好的區(qū)分基本類型值(null除外);
但對部分引用類型值就無能為力,比如它無法區(qū)分object、null和Array,此時(shí)就要借助instanceof操作符;
instanceof操作符
instanceof操作符可以識(shí)別某個(gè)變量是否是某個(gè)對象的實(shí)例,借助這個(gè)功能可以進(jìn)一步區(qū)分object、Array和null三者的區(qū)別;
但是,這還不足以區(qū)分object和Array,所以還需要借助第3個(gè)方法識(shí)別數(shù)據(jù)類型;
Object.prototype.toString()方法
數(shù)據(jù)類型轉(zhuǎn)換之前在前面的文章分散到變量部分講解了一下,這里為了文章的系統(tǒng)性,重新將數(shù)據(jù)類型轉(zhuǎn)換的方法歸納一下:
任何類型數(shù)據(jù)轉(zhuǎn)換為數(shù)值有4種方法:Number()轉(zhuǎn)型函數(shù)、parseInt()、parseFloat()和+操作符;
上述四種方法的區(qū)別在于Number和+作用一樣可以對任何類型數(shù)據(jù)進(jìn)行轉(zhuǎn)型,而parseInt和parseFloat只能對數(shù)值和字符串轉(zhuǎn)型;
轉(zhuǎn)換為字符串包括3種方法:轉(zhuǎn)型函數(shù)String(),toString()方法(null和undefined會(huì)報(bào)錯(cuò))和""(作用等同于String());
轉(zhuǎn)換為布爾值有2種方法:轉(zhuǎn)型函數(shù)Boolean()和!!
實(shí)現(xiàn)對象的深淺拷貝,首先要識(shí)別變量的數(shù)據(jù)類型,上一節(jié)我們已經(jīng)知道識(shí)別數(shù)據(jù)類型的方法,下面我們可以定義識(shí)別數(shù)據(jù)類型的函數(shù)并將其封裝在一個(gè)對象(通用庫)中;
通用庫的建立
(function(window){ window.Util = (function(){ // 1.判斷數(shù)據(jù)類型 function isNumber(el){ return typeof el === "number"; }; function isString(el){ return typeof el === "string"; } function isBoolean(el){ return typeof el === "boolean"; } function isObject(el){ return Object.prototype.toString.call(el) === "[object Object]" }; function isArray(el){ return Object.prototype.toString.call(el) === "[object Array]" }; function isSimpleType(el){ return this.isNumber(el) || this.isString(el) || this.isBoolean(el) }; return { isNumber:isNumber, isString:isString, isBoolean:isBoolean, isObject:isObject, isArray:isArray, isSimpleType:isSimpleType, } })(); })(window);
上述代碼首先使用數(shù)據(jù)類型判斷的方法判斷傳入的參數(shù)的數(shù)據(jù)類型;
//對象或數(shù)組的拷貝 function shallowCopy(oldObj){ var newObj = {}; for(var key in oldObj){ if(!this.isSimpleType(oldObj[key])){ return "It doesn"t match shallowCopy" } newObj[key] = oldObj[key] } return newObj; }; function cloneObject(oldObj){ var newObj = {}; for(var key in oldObj){ if(this.isObject(oldObj[key])){ newObj[key] = cloneObject(oldObj[key]) }else if(this.isArray(oldObj[key])){ newObj[key] = cloneArray(oldObj[key]) }else if(this.isSimpleType(oldObj[key])){ newObj[key] = oldObj[key] } } return newObj; }; function cloneArray(oldArr){ var newArr = []; for(var i = 0;i上面的代碼deepClone方法將對數(shù)組或?qū)ο蟮膶傩赃M(jìn)行遍歷,如果發(fā)現(xiàn)屬性值是基本類型,則直接賦值,如果發(fā)現(xiàn)是引用類型則調(diào)用cloneArray或cloneObject方法,這兩個(gè)方法將繼續(xù)遍歷引用類型的屬性值,直到遞歸到屬性值是基本類型值,從而完成對象的"深拷貝";
5.小結(jié)
通用庫的代碼地址將發(fā)布在【github】,以供童鞋參考;通過閱讀本文,我們可以知道:
變量的數(shù)據(jù)類型根據(jù)其在內(nèi)存中的存儲(chǔ)方式,可分為基本類型值和引用類型值;
基本類型值是保存在棧內(nèi)存中的簡單數(shù)據(jù)段,包括數(shù)值、字符串、布爾值、null和undefend,變量保存的是基本類型值的實(shí)際值;
引用類型值是保存在堆內(nèi)存的對象,變量保存的是指向?qū)ο蟮闹羔槪?/p>
判斷數(shù)據(jù)類型的方法包括typeof操作符、instanceof操作符、Object.prototype.toString()方法;
數(shù)據(jù)類型轉(zhuǎn)換的方法有轉(zhuǎn)換為數(shù)值、轉(zhuǎn)換為字符串和轉(zhuǎn)換為布爾值;
我們通過建立一個(gè)通用庫的方式,封裝對象的深淺拷貝方法;
參考資料
最后,JavaScript核心知識(shí)點(diǎn)的基本語法部分將暫且告一段落,下一章將進(jìn)入JavaScript核心知識(shí)點(diǎn)的標(biāo)準(zhǔn)庫部分;《JavaScript高級程序設(shè)計(jì)(第3版)》
《JavaScript標(biāo)準(zhǔn)參考教程》——阮一峰
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/86621.html
摘要:目錄導(dǎo)語包裝對象的理解三大包裝對象的知識(shí)點(diǎn)小結(jié)導(dǎo)語包裝對象是為了彌補(bǔ)基本數(shù)據(jù)類型的非對象特性而產(chǎn)生的,對于基本類型值而言,本來是不存在屬性和方法的,但是我們可以在使用字面量創(chuàng)建字符串時(shí),調(diào)用例如的方法,那么其內(nèi)在原理究竟是什么呢閱讀完本篇文 目錄 導(dǎo)語 1. 包裝對象的理解 2. 三大包裝對象的知識(shí)點(diǎn) 3. 小結(jié) 導(dǎo)語 包裝對象是為了彌補(bǔ)基本數(shù)據(jù)類型的非對象特性而產(chǎn)生的,對于基本類型...
摘要:執(zhí)行環(huán)境的類型有兩種全局全局執(zhí)行環(huán)境局部函數(shù)執(zhí)行環(huán)境每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名但任何環(huán)境都不能通過向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。內(nèi)部可通過作用域鏈訪問外部,外部不能訪問內(nèi)部。 變量、作用域和內(nèi)存問題 ECMAScript 數(shù)據(jù)類型 基本類型(5種): Undefined,Null,Boolean,Number,String typeof() 檢測...
摘要:實(shí)際上,是禁止這樣做的。傳值和傳址基本數(shù)據(jù)類型賦值基本數(shù)據(jù)類型的賦值是在內(nèi)存中新開辟一段棧內(nèi)存,然后再把再將值賦值到新的棧中。結(jié)果見輸出,可以看出來,無論是修改賦值得到的對象和淺拷貝得到的都會(huì)改變原始數(shù)據(jù)。 存儲(chǔ)問題:深拷貝和淺拷貝的主要區(qū)別:在內(nèi)存中的存儲(chǔ)類型(堆和棧)不同堆:動(dòng)態(tài)分配的內(nèi)存,大小不定也不會(huì)自動(dòng)釋放棧:自動(dòng)分配的內(nèi)存,由系統(tǒng)自動(dòng)釋放數(shù)據(jù)類型: 基本數(shù)據(jù)類型: jav...
摘要:本文將介紹一段使用隱式類型轉(zhuǎn)換輸出的代碼,并講解具體的轉(zhuǎn)換過程。代碼轉(zhuǎn)換過程我們分四部分講解具體的轉(zhuǎn)換過程,一個(gè)空數(shù)組,緊跟在數(shù)組后面的的語義應(yīng)該是表示屬性操作,類似于中的作用,而不是表示數(shù)組。 本文將介紹一段使用JavaScript隱式類型轉(zhuǎn)換輸出nb的代碼,并講解具體的轉(zhuǎn)換過程。 預(yù)備知識(shí) 請先閱讀文章ECMAScript7規(guī)范中的ToPrimitive抽象操作。 代碼 ([][[...
摘要:在操作對象時(shí),實(shí)際上是在操作對象的引用而不是實(shí)際的對象。為此,引用類型的值是按引用訪問的。標(biāo)記清除是目前主流的垃圾收集算法,這種算法的思想是給當(dāng)前不使用的值加上標(biāo)記,然后再回收其內(nèi)存 1.在操作對象時(shí),實(shí)際上是在操作對象的引用而不是實(shí)際的對象。為此,引用類型的值是按引用訪問的。 2.當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值時(shí),兩個(gè)變量實(shí)際上將引用同一個(gè)對象,因此,改變其中一個(gè)變量,就會(huì)...
閱讀 3453·2019-08-30 10:54
閱讀 3153·2019-08-29 16:38
閱讀 2175·2019-08-26 14:06
閱讀 1516·2019-08-23 15:39
閱讀 3040·2019-08-23 15:37
閱讀 2887·2019-08-23 13:50
閱讀 3194·2019-08-22 17:14
閱讀 2381·2019-08-22 15:44