前言
錯誤理解:
之前對Js基本包裝型別的理解是,當我們創建了一個基本型別的變數時,Js會自動為我們將其包裝(轉換)成基本包裝型別的實體,所以我們才能直接呼叫它的屬性的方法,
// 因為基本包裝型別的存在,下邊代碼可以執行,我們可以直接對基本型別呼叫方法
let str = 'hello'
substr = str.substring(2)
其實關于str到底是什么型別,我也沒有太在意過,今天偶爾的一個測驗卻讓我發現事情沒有那么簡單,
可以看到,str不是一個實體物件,而是一個基本型別變數
var str = "string"
console.log(str instanceof String) //false
console.log(typeof str) //string
所以這也就觸發了我今天對基本包裝型別的探究,總結如下:
基本包裝型別
為了便于操作基本型別值,ECMAScript提供了一些特殊的參考型別:比如Boolean、Number和String等,這些型別與其他參考型別相似,但具有與各自的基本型別相應的特殊行為,
除了 null 和 undefined之外,所有基本型別都有其對應的包裝物件:
StringNumberBigIntBooleanSymbol
按道理基本資料型別是沒有屬性和方法的,物件才有屬性和方法,
但下面代碼卻可以執行:
// 下面代碼有什么問題?
let str = 'hello';
substr = str.substring(2);
原理
實際上,每當我們對一個保存了基本型別值(比如number,string和boolean)的變數呼叫方法(或者訪問屬性)的時候,后臺就會創建一個對應的基本包裝型別的物件,對他們呼叫我們所指定的方法來得到我們想要的資料,
具體程序如下:
-
根據物件保存的基本型別值,創建對應型別的實體物件
-
在這個實體上呼叫我們所指定的方法
-
立即銷毀這個實體
上邊宣告了str變數,并對其呼叫substring方法的代碼等同于下邊代碼:
let str = 'hello';
// 1. 生成臨時變數,保存基本包裝型別實體
var temp = new String(str);
// 2. 對實體呼叫方法
substr = temp.substring();
// 3. 銷毀臨時變數
temp = null;
參考型別與基本包裝型別的主要區別就是物件的生存期,使用new創建的參考型別實體當執行流離開當前作用域之前,都一直保存在記憶體中,而自動創建的基本包裝型別的物件,則只存在于一行代碼執行的瞬間,然后就被銷毀,這就意味著我們不能給基本包裝型別添加屬性和方法,
let s = 'JavaScript';
s.language = 'ECMAScript';
console.log(s.language); // undefined
上邊代碼試圖給s添加一個language屬性,但是當我們再次輸出該屬性的時候卻得到undefined,
這是因為s.language = 'ECMAScript';這句代碼執行時,Js內部創建了一個String型別的實體,并在這個實體身上添加了language屬性,但是這行代碼執行完畢之后,這個實體馬上就被銷毀了,當我們執行console.log(s.language);這句代碼時,又重新創建了一個實體物件,這個實體物件和上一句代碼所創建的實體物件不是一個,自然也沒有language屬性,
一般來說,不推薦直接宣告基本包裝型別物件,
//不推薦
let n = new Number(10);
let s = new String('JS');
let b = new Boolean(false);
我們只需要知道基本包裝型別物件身上(準確的來說是他的原型身上)有哪些方法,我們直接宣告基本型別變數呼叫即可,
總結
- 基本包裝型別的實體會在我們呼叫一些基本型別變數方法(或屬性)的時候被自動創建
- 我們對基本型別變數呼叫的方法(或訪問屬性),Js底層會對基本包裝型別實體操作
- 基本包裝型別的實體只會存在于一行代碼執行的一瞬間,然后就會被立即銷毀
- 不推薦手動創建基本包裝型別實體
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/413461.html
標籤:其他
下一篇:關于 JS 閉包看這一篇就夠了
