JS中‘hello’與new String(‘hello’)引出的問(wèn)題詳解
定義一個(gè)字符串
在工作中我們大概有3種方法去定義一個(gè)字符串:
1. var str = 'hello';
2. var str1 = String('hello');
3. var str2 = new String('hello');
(下文直接會(huì)帶 以上三個(gè)變量....)
這三種方法定義出來(lái)的 'hello',都有自己的屬性 例如lengh,有自己的方法例如: indexOf(),在日常工作定義中也沒(méi)有感覺(jué)到任何的不同。
那是否深入過(guò),
1.這三種方式定義出來(lái)的'hello',是否是一樣的呢?
2.為什么基本類型可以直接調(diào)用其對(duì)應(yīng)的方法呢?
這三種方式定義出來(lái)的'hello',是否是一樣的呢?
console.log(str === str1) //true console.log(str === str2) //false console.log(str1 === str2) //false
我們可以發(fā)現(xiàn) 最后一種方式定義的 與上面兩種方式定義的 不相等。
???
首先我們知道一個(gè)東西 就是:
new 出來(lái)的一定是對(duì)象。
所以分別 打出三個(gè)的類型:
console.log(typeof str) //string console.log(typeof str1) // string console.log(typeof str2) //object
所以這也就是為什么不會(huì)嚴(yán)格相等的原因。
引出數(shù)據(jù)類型 與 堆棧之間的關(guān)系
嘗試深入理解原因:
我們知道,String,Number,Boolean在JS中是基本類型,基本類型是存儲(chǔ)在棧(stack)內(nèi)存中的,數(shù)據(jù)大小確定,內(nèi)存空間大小可以分配。
而引用類型是存儲(chǔ)在堆(heap)內(nèi)存中的,例如對(duì)象, 棧中存在的僅僅是一個(gè)堆的指針,這也就是我們?nèi)粘S龅?a = {num:1}, b=a, b.num1 = 2, 那么a.num1 也為2 的原因。因?yàn)閍,b同時(shí)指向同一個(gè)地址。
前兩種方式定義出來(lái)的是在棧中并且值相等,而第三種方法定義出來(lái)的僅僅是棧中的一個(gè)指針。
所以這也是為什么 三種方式定義出來(lái)的不一樣。
為什么基本類型可以直接調(diào)用其對(duì)應(yīng)的方法呢?
嘗試:
console.log(str.length) // 5 str.say = 'world' console.log(str.say) //undefined console.log(str1.lengh) // 5 str1.say = 'world' console.log(str1.say) //undefined console.log(str2.lengh) // 5 str2.say = 'world' console.log(str.say) //world
引出包裝對(duì)象和原始資料類型
我們發(fā)現(xiàn)第一種第二種方式均可訪問(wèn)lengh屬性,
但是為什么我們并不能自定義一個(gè)屬性并進(jìn)行訪問(wèn)?
數(shù)字、字符串、布爾三者,在JS中稱為原始的(primitives)資料類型,而 new String(), new Number() 就是包裝對(duì)象。
包裝對(duì)象也是對(duì)象。
這也就是為什么 我們打印 三種類型分別為 : string(原始資料類型) , string(原始資料類型) , object(包裝對(duì)象).
我們可以理解 new 出來(lái)的 str2 對(duì)象有 String 的一系列方法
console.log(str2.indexOf === String.prototype.indexOf) // true
那嘗試一下 第一種第二種方法 是否有同樣的true?
console.log(str.indexOf === String.prototype.indexOf) //true console.log(str1.indexOf === String.prototype.indexOf) //true
但是:
str instanceof String // false str1 instanceof String // false
str 又 不屬于String 卻擁有 String 的方法?????
因?yàn)?
這是JS中的設(shè)計(jì)。
這是JS中的設(shè)計(jì)。
這是JS中的設(shè)計(jì)。
原始資料類型的方法與屬性是"借"來(lái)的
一個(gè)原始的資料類型值,并沒(méi)有如對(duì)象會(huì)有屬性或方法,
原始的資料類型在運(yùn)算時(shí)用的屬性與方法,是向包裝對(duì)象"借來(lái)"的用的,
所以原始資料類型是可以向 new String() 或者 new Number() 借來(lái)所有的方法。但是自己本身卻沒(méi)有屬性和方法。
所以這也就是為什么第一種第二種我們無(wú)法去自定義屬性卻可以使用對(duì)應(yīng)類型的方法的原因
總結(jié):
1.第一種和第二種方法定義出來(lái)的是原始資料類型
并儲(chǔ)存于棧中,
并向包裝對(duì)象(new ..())借來(lái)方法和屬性.
2.第三種是 包裝對(duì)象,
棧中儲(chǔ)存堆指針,
堆中儲(chǔ)存內(nèi)容。
所以這也是發(fā)生一系列看似不正常但是又正常的事情的原因,
哈哈哈哈哈哈哈哈。
當(dāng)然還有很多的東西,既然牽扯到了堆棧,
那么又不得不了解一下堆棧到底是什么,
有什么區(qū)別等等。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- JS中使用new Option()實(shí)現(xiàn)時(shí)間聯(lián)動(dòng)效果
- 原生JS封裝_new函數(shù)實(shí)現(xiàn)new關(guān)鍵字的功能
- JavaScript new對(duì)象的四個(gè)過(guò)程實(shí)例淺析
- 詳解Javascript中new()到底做了些什么?
- javascript中new Array()和var arr=[]用法區(qū)別
- 用Newtonsoft將json串轉(zhuǎn)為對(duì)象的方法(詳解)
- js中new一個(gè)對(duì)象的過(guò)程
- JavaScript中new運(yùn)算符的實(shí)現(xiàn)過(guò)程解析
相關(guān)文章
使用Require.js封裝原生js輪播圖的實(shí)現(xiàn)代碼
這篇文章主要介紹了使用Require.js封裝原生js輪播圖的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-06-06js利用clipboardData實(shí)現(xiàn)截屏粘貼功能
這篇文章主要為大家詳細(xì)介紹了js利用clipboardData實(shí)現(xiàn)截屏粘貼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10js 顯示日期時(shí)間的實(shí)例(時(shí)間過(guò)一秒加1)
下面小編就為大家?guī)?lái)一篇js 顯示日期時(shí)間的實(shí)例(時(shí)間過(guò)一秒加1)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10js通過(guò)window.open(url)下載文件并修改文件名
這篇文章主要給大家介紹了關(guān)于js如何通過(guò)window.open(url)下載文件并修改文件名的相關(guān)資料,我們知道下載文件是一個(gè)非常常見(jiàn)的需求,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08解決js數(shù)據(jù)包含加號(hào)+通過(guò)ajax傳到后臺(tái)時(shí)出現(xiàn)連接錯(cuò)誤
測(cè)試過(guò)程中發(fā)現(xiàn)js數(shù)據(jù)包含加號(hào)+通過(guò)ajax傳到后臺(tái)時(shí)出現(xiàn)連接錯(cuò)誤,刪除+,鏈接暢通了,果然是這塊問(wèn)題,對(duì)加號(hào)進(jìn)行轉(zhuǎn)義2013-08-08微信小程序?qū)崿F(xiàn)星星評(píng)價(jià)效果
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)星星評(píng)價(jià)效果,支持多個(gè)條目評(píng)價(jià),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11JavaScript中的apply()方法和call()方法使用介紹
我們發(fā)現(xiàn)apply()和call()的真正用武之地是能夠擴(kuò)充函數(shù)賴以運(yùn)行的作用域,如果我們想用傳統(tǒng)的方法實(shí)現(xiàn)2012-07-07