淺析JS給原始數(shù)據(jù)類型加屬性和方法為什么不報錯
前言
近日看到一道阿里前端面試題,由于不了解JS包裝類的特性,果然不出意外的做錯了。題目如下:
var str = 'abc'
str += 1
var test = typeof (str)
if (test.length == 6) {
test.sign = 'typeOf的返回結(jié)果可能為String'
}
console.log(test.sign)
上述代碼的輸出結(jié)果是什么?報錯?還是typeOf的返回結(jié)果可能為String?最終結(jié)果都不是上面兩種,最后輸出結(jié)果為undefined,為什么會這樣呢?為什么徹底理解此類問題,我們有必要深入了解一下包裝類。
我們都知道JavaScript中的數(shù)據(jù)類型分為兩種,第一種是原始數(shù)據(jù)類型,另一種是引用數(shù)據(jù)類型(也稱為復雜數(shù)據(jù)類型)。
原始數(shù)據(jù)類型
let a = 'hello' let b = 123 let c = true let u =undefined let n = null
原始數(shù)據(jù)類型主要分為六種,如上述代碼所示,字符串類型、Number類型、Boolean類型、undefined類型、null類型。還有一種是ES6新增的Symbol類型(表示獨一無二的值,Symbol最大的用途是用來定義對象的唯一屬性名)
特點
這些原始數(shù)據(jù)類型都是不可變的,這意味著它們的值一旦被創(chuàng)建,就不能被修改,也意味著不能給原始數(shù)據(jù)類型加屬性和方法,屬性和方法是對象獨有的。在JavaScript中,變量存儲原始數(shù)據(jù)類型的值,而不是直接存儲數(shù)據(jù)本身。原始數(shù)據(jù)類型的比較是基于它們的值,而不是引用,因此兩個具有相同值的原始數(shù)據(jù)類型變量將被認為相等。
引用數(shù)據(jù)類型
在JavaScript中,除了原始數(shù)據(jù)類型(字符串、數(shù)字、布爾、未定義、空值和符號)之外,還有一種復雜的數(shù)據(jù)類型,被稱為引用數(shù)據(jù)類型。引用數(shù)據(jù)類型是一種用于存儲和處理更復雜數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)類型。它們不直接包含實際數(shù)據(jù),而是存儲對數(shù)據(jù)的引用。JavaScript中的引用數(shù)據(jù)類型包括對象(Object)、數(shù)組(Array)、函數(shù)(Function)、正則表達式(RegExp)、日期(Date)等。下面簡單介紹一下部分引用數(shù)據(jù)類型。
對象
對象是JavaScript中最常見的引用數(shù)據(jù)類型。它是一個無序的數(shù)據(jù)集合,包含鍵值對。每個鍵值對的鍵是字符串,值可以是任意數(shù)據(jù)類型,包括原始數(shù)據(jù)類型和其他引用數(shù)據(jù)類型。對象用花括號 {} 定義。例如:
let person = {
name : '小明',
age: 18,
hobby: basketball
}
數(shù)組
數(shù)組是一種有序的集合,可以存儲多個值,每個值可以是任意數(shù)據(jù)類型,包括原始數(shù)據(jù)類型和其他引用數(shù)據(jù)類型。數(shù)組用方括號 [] 定義。例如:
let num =[1,2,3,4]
函數(shù)
函數(shù)是JavaScript中的一種對象,也是引用數(shù)據(jù)類型的一種。函數(shù)可以被定義、傳遞、賦值和作為參數(shù)傳遞給其他函數(shù)。函數(shù)用 function 關鍵字定義,如下:
function sayHello(){
console.log("Hello")
}
正則表達式
正則表達式是一種用于匹配字符串模式的對象。它可以用于字符串的搜索、替換、分割等操作,提供了強大的文本處理功能。
let pattern = /[0-9]+/; // 匹配一個或多個數(shù)字
日期
日期對象用于處理日期和時間。它提供了各種方法來操作日期和時間,例如獲取年、月、日、時、分、秒等信息,以及執(zhí)行日期和時間的計算。
let nowDate = new Date();
引用數(shù)據(jù)類型在JavaScript中用于處理更復雜的數(shù)據(jù)結(jié)構(gòu)和操作,它們提供了靈活性和功能性,使得JavaScript成為一種強大的編程語言。通過組合使用原始數(shù)據(jù)類型和引用數(shù)據(jù)類型,開發(fā)者可以處理各種類型的數(shù)據(jù)和問題。
介紹了一下JavaScript中的數(shù)據(jù)類型,接下來我們就可以講解一下什么是包裝類了。
在JavaScript中,包裝類(Wrapper Objects)是一種特殊的對象,它們用來包裝原始數(shù)據(jù)類型(如字符串、數(shù)字和布爾值),使其具備對象的方法和屬性。這些包裝類提供了對原始數(shù)據(jù)類型的操作,例如字符串的長度、數(shù)字的精度等。
我們在介紹原始數(shù)據(jù)類型的時候曾講到過,原始數(shù)據(jù)類型都是不可變的,這意味著它們的值一旦被創(chuàng)建,就不能被修改,也意味著不能給原始數(shù)據(jù)類型加屬性和方法,屬性和方法是對象獨有的 上述加粗字體這些規(guī)則的存在顯然是必要的,正是有了這些規(guī)則,使得我們不能直接給原始數(shù)據(jù)隨便添加屬性和方法,這使得原始數(shù)據(jù)往往都是很簡單的。而在我們的日常代碼練習中,你一定有用到過一些原始類型數(shù)據(jù)自帶的方法,比如字符串類型的數(shù)據(jù)往往都會自帶一個length方法,它能夠直接返回一個字符串的長度,由于上述規(guī)則的限定,顯然我們不能直接修改字符串的長度。這確保的數(shù)據(jù)的完整性,使原始數(shù)據(jù)在創(chuàng)建后不會被無意或者惡意更改,尤其是在多線程或者并發(fā)編程環(huán)境中尤為重要。等等!我們剛剛不是講到原始數(shù)據(jù)不能附加屬性和方法嗎?那字符串類型的length方法是哪來的呢?這就是我們要特別介紹的包裝類。
包裝類
包裝類的設計正是為了給原始數(shù)據(jù)類型增加方法和屬性。
在JavaScript引擎內(nèi)部,會對原始數(shù)據(jù)類型進行了一些封裝和包裝,使其能夠調(diào)用一些內(nèi)置方法和屬性。當你嘗試訪問原始數(shù)據(jù)類型的方法或?qū)傩詴r,JavaScript引擎會自動將原始數(shù)據(jù)類型包裝成對應的包裝對象,然后調(diào)用相應的方法或?qū)傩?,然后再將包裝對象銷毀。這個過程被稱為"自動包裝"。例如,當你訪問字符串的 length 屬性時,JavaScript引擎會在內(nèi)部將字符串包裝成 String 對象,然后訪問其 length 屬性。這一切都是自動完成的,你無需手動創(chuàng)建包裝對象。雖然原始數(shù)據(jù)類型不能附加自定義屬性和方法,但這種自動包裝機制使得它們可以調(diào)用一些內(nèi)置的屬性和方法,使其更方便。不過需要注意,包裝對象在訪問完成后會被銷毀,所以無法在原始數(shù)據(jù)類型上保留自定義屬性或方法。如果需要自定義屬性和方法,通常會使用對象類型來實現(xiàn)。
了解了這些,我們再回到最初看到那道面試題,嘗試著去分析它,相信問題就迎刃而解了。
var str = 'abc'
str += 1
var test = typeof (str)
if (test.length == 6) {
test.sign = 'typeOf的返回結(jié)果可能為String'
}
console.log(test.sign)
分析題目
- str是一個字符串類型,當它和1相加時我們能夠知道,字符串和其他東西相加會將它‘同化’最終也變?yōu)樽址?,于是,我們得到得str變?yōu)?#39;abc1'。
- typeof會讀取到一個數(shù)據(jù)并返回它的類型,最終我們得到test被賦值為string.
- 由于string的長度為6,進入if判斷語句。
- 但是test為字符串類型,為原始數(shù)據(jù),它本身不能添加屬性和方法,但由于包裝類存在的緣故,test.sign = 'typeOf的返回結(jié)果可能為String' 會被執(zhí)行為:new String(test).sign = 'typeOf的返回結(jié)果可能為String' 然后delete被銷毀掉。
- 接著,我們退出if語句,控制臺輸出test.sign,由于我們之前創(chuàng)建的test.sign已經(jīng)被銷毀,但此時又讀到了test.sign,JavaScript引擎又會生成 *new String(test).sign *
- 但由于 new String(test).sign并未被賦值,所以最終我們得到結(jié)果:undefined。
以上就是淺析JS給原始數(shù)據(jù)類型加屬性和方法為什么不報錯的詳細內(nèi)容,更多關于JS原始數(shù)據(jù)類型的資料請關注腳本之家其它相關文章!
相關文章
JavaScript學習小結(jié)(一)——JavaScript入門基礎
本教程比較適合javascript初學者,對javascript基本知識的小結(jié)包括變量,基本類型等知識點,需要的朋友一起來學習吧2015-09-09
JavaScript字符和ASCII實現(xiàn)互相轉(zhuǎn)換
這篇文章主要介紹了JavaScript字符和ASCII實現(xiàn)互相轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
javascript 判斷字符串是否包含某字符串及indexOf使用示例
js javascript 判斷字符串是否包含某字符串,String對象中查找子字符及indexOf具體使用,感興趣的朋友可以參考下2013-10-10
IE6-IE9使用JSON、table.innerHTML所引發(fā)的問題
這篇文章主要介紹了IE6-IE9使用JSON、table.innerHTML所引發(fā)的問題 ,需要的朋友可以參考下2015-12-12

