摘要:的碼點被稱為基本字符區域。關于的介紹,我準備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數前不能使用命令,否則會報錯。
筆記說明
重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學習【原文有winter的語音】,如有侵權請聯系我,郵箱:kaimo313@foxmail.com。JavaScript類型有哪些你不知道的細節? winter提了幾個問題測試:能回答對幾個?
1、為什么有的編程規范要求用 void 0 代替 undefined?
2、字符串有最大長度嗎?
3、0.1 + 0.2 不是等于 0.3 么?為什么 JavaScript 里不是這樣的?
4、ES6 新加入的 Symbol 是個什么東西?
5、為什么給對象添加的方法能用在基本類型上?
如果有點猶豫,不妨看看下面的介紹,或者找找資料溫習一下。類型
Undefined
Null
Boolean
String
Number
Symbol
Object
1、Undefined、NullUndefined:
Undefined 類型表示未定義,它的類型只有一個值,就是 undefined
任何變量在賦值前是 Undefined 類型、值為 undefined
JavaScript 的代碼 undefined 是一個變量,而并非是一個關鍵字,這是 JavaScript 語言公認的設計失誤之一
為了避免無意中被篡改,可以使用 void 0 來獲取 undefined 值。
Null:
Null 類型也只有一個值,就是 null,它的語義表示空值
與 undefined 不同,null 是 JavaScript 關鍵字
在任何代碼中,都可以用 null 關鍵字來獲取null值
2、StringString 用于表示文本數據
String 有最大長度是 2^53 - 1
字符串的最大長度,實際上是受字符串的編碼長度影響的。
Note: 現行的字符集國際標準,字符是以 Unicode 的方式表示的,每一個 Unicode 的碼點表示一個字符,理論上,Unicode 的范圍是無限的。UTF 是 Unicode 的編碼方式,規定了碼點在計算機中的表示方法,常見的有 UTF16 和 UTF8。Unicode 的碼點通常用 U+??? 來表示,其中 ??? 是十六進制的碼點值。0-65536(U+0000 - U+FFFF)的碼點被稱為基本字符區域(BMP)。3、Number
JavaScript 中的 Number 類型有 18437736874454810627(即 2^64-2^53+3) 個值
NaN,占用了 9007199254740990,這原本是符合 IEEE 規則的數字
Infinity,無窮大
-Infinity,負無窮大
根據雙精度浮點數的定義,Number 類型中有效的整數范圍是-0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 無法精確表示此范圍外的整數
根據浮點數的定義,非整數的 Number 類型無法用 ==(=== 也不行)來比較
關于javaScript中 0.1 + 0.2 == 0.3 ? 這個問題的解釋:
console.log( 0.1 + 0.2 == 0.3); >> false
輸出結果為false,說明兩邊不相等,這是浮點運算特點導致的,實際上,這里錯誤的不是結論,而是比較的方法,正確的比較方法是使用javaScript提供的最小精度值:
我們可以查找MDN文檔的Number可以找到屬性EPSILON
Number.EPSILON:兩個可表示數字之間的最小間隔
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON); >> true
這樣的比較輸出結果為true,檢查等式左右兩邊差的絕對值是否小于最小精度,才是正確的比較浮點數的方法。
4、Symbol關于Symbol的介紹,我準備用ES6文檔-阮一峰來做一些介紹,具體的可以參考文檔
4.1、ES6 引入Symbol的原因ES5 的對象屬性名都是字符串,這容易造成屬性名的沖突。ES6引入了一種新的原始數據類型Symbol,表示獨一無二的值。從根本上防止屬性名的沖突。4.2、介紹
凡是屬性名屬于 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產生沖突。
4.2.1、Symbol 值通過Symbol函數生成,先來一段代碼:
let s = Symbol(); typeof s >> "symbol"
上面代碼中,變量s就是一個獨一無二的值。s是Symbol數據類型。
4.2.2、Symbol函數可以接受一個字符串作為參數,表示對 Symbol 實例的描述
let s1 = Symbol("foo"); let s2 = Symbol("bar"); s1 >> Symbol(foo) s2 >> Symbol(bar) s1.toString() >> "Symbol(foo)" s2.toString() >> "Symbol(bar)"
上面代碼中,s1和s2是兩個 Symbol 值。如果不加參數,它們在控制臺的輸出都是Symbol(),不利于區分。有了參數以后,就等于為它們加上了描述,輸出的時候就能夠分清,到底是哪一個值。
4.2.3、如果 Symbol 的參數是一個對象,就會調用該對象的toString方法,將其轉為字符串,然后才生成一個 Symbol 值。
const obj = { a: "123123", toString() { return "iuoisigud"; } }; const sym = Symbol(obj); sym // Symbol(iuoisigud)
4.2.4、Symbol函數的參數只是表示對當前 Symbol 值的描述,因此相同參數的Symbol函數的返回值是不相等的。
// 沒有參數的情況 let s1 = Symbol(); let s2 = Symbol(); s1 === s2 // false // 有參數的情況 let s1 = Symbol("foo"); let s2 = Symbol("foo"); s1 === s2 // false
4.2.5、Symbol 值不能與其他類型的值進行運算,會報錯。
let sym = Symbol("My symbol"); "your symbol is " + sym // TypeError: can"t convert symbol to string `your symbol is ${sym}` // TypeError: can"t convert symbol to string
4.2.6、Symbol 值可以顯式轉為字符串,也可以轉為布爾值,但是不能轉為數值。
let sym = Symbol("My symbol"); String(sym) // "Symbol(My symbol)" sym.toString() // "Symbol(My symbol)" let sym = Symbol(); Boolean(sym) // true !sym // false Number(sym) // TypeError sym + 2 // TypeError
4.2.7、其他的一些屬性可以去看ES6文檔-阮一峰
4.3、注意Symbol函數前不能使用new命令,否則會報錯。這是因為生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由于 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似于字符串的數據類型。5、Object
Object 是 JavaScript 中最復雜的類型,也是 JavaScript 的核心機制之一。為什么給對象添加的方法能用在基本類型上?
回答:“運算符提供了裝箱操作,它會根據基礎類型構造一個臨時對象,使得我們能在基礎類型上調用對應對象的方法?!?/p>
比如原型上添加方法,也可以應用于基本類型:
Symbol.prototype.hello = () => console.log("hello"); var a = Symbol("a"); console.log(typeof a); //symbol,a 并非對象 a.hello(); //hello,有效6、類型轉換 6.1、臭名昭著的“ == ”運算
因為 JS 是弱類型語言,所以類型轉換發生非常頻繁
“ == ”試圖實現跨類型的比較,它的規則復雜到幾乎沒人可以記住。
6.2、轉換規則 6.3、StringToNumber字符串到數字的類型轉換,存在一個語法結構,類型轉換支持十進制、二進制、八進制和十六進制
比如:
Number("0xFF") >> 2556.4、裝箱轉換
裝箱(boxing):值類型實例到對象的轉換,它暗示在運行時實例將攜帶完整的類型信息,并在堆中分配。
每一種基本類型 Number、String、Boolean、Symbol 在對象中都有對應的類,所謂裝箱轉換,正是把基本類型轉換為對應的對象,它是類型轉換中一種相當重要的種類。
例子:利用一個函數的 call 方法來強迫產生Symbol裝箱
var symbolObject = (function() { return this; }).call(Symbol("a")); console.log(typeof symbolObject); //object console.log(symbolObject instanceof Symbol); //true console.log(symbolObject.constructor == Symbol); //true
例子:使用內置的 Object 函數,我們可以在 JavaScript 代碼中顯式調用裝箱能力。
var symbolObject = Object(Symbol("a")); console.log(typeof symbolObject); //object console.log(symbolObject instanceof Symbol); //true console.log(symbolObject.constructor == Symbol); //true
每一類裝箱對象皆有私有的 Class 屬性,這些屬性可以用 Object.prototype.toString 獲?。?/pre>var symbolObject = Object(Symbol("a")); console.log(Object.prototype.toString.call(symbolObject)); >> [object Symbol]6.5、拆箱轉換拆箱(unboxing):是將引用類型轉換為值類型6.5.1、在 JavaScript 標準中,規定了 ToPrimitive 函數,它是對象類型到基本類型的轉換
toPrimitive(input, preferedType)input是輸入的值,preferedType是期望轉換的類型,它可以是字符串,也可以是數字。
inputType | Result |
---|---|
Undefined | input argument |
Null | input argument |
Boolean | input argument |
Number | input argument |
String | input argument |
Object | 忽略 第二個參數 hint PreferredType 直接調用內置方法 [[DefaultValue]] |
6.5.2、如果轉換的類型是number,會執行以下步驟:參考博客
如果input是原始值,直接返回這個值;
否則,如果input是對象,調用input.valueOf(),如果結果是原始值,返回結果;
否則,調用input.toString()。如果結果是原始值,返回結果;
否則,拋出錯誤。
6.5.3、如果轉換的類型是String,2和3會交換執行,即先執行toString()方法。
例子1:先將兩個操作數轉換為string,然后進行拼接
[] + [] >> "" [] -----> "" [] -----> "" [] + [] = ""
例子2:先將兩個操作數轉換為string,然后進行拼接
[] + {} >> "[object Object]" // 解釋 [] -----> "" {} -----> "[object Object]" [] + {} = "[object Object]"
例子3:js解釋器會將開頭的 {} 看作一個代碼塊,而不是一個js對象
{} + [] >> 0 // 真正參與運算的是 + [] // {} + [] 等價于 + []7、規范類型
List 和 Record: 用于描述函數傳參過程。
Set:主要用于解釋字符集等。
Completion Record:用于描述異常、跳出等語句執行過程。
Reference:用于描述對象屬性訪問、delete 等。
Property Descriptor:用于描述對象的屬性。
Lexical Environment 和 Environment Record:用于描述變量和作用域。
Data Block:用于描述二進制數據。
8、補充閱讀 typeof 的運算結果,與運行時類型的規定有很多不一致的地方(typeof 的設計是有缺陷的) 個人總結在整理知識點的時候,我就發現,我可能是真的劃水醬_(:3」∠)_,里面大部分的東西很模糊,有點都不清不楚的,還有的沒有聽過,看來要好好打打基礎了,現在前端的發展過于太快了,而自己的基礎又不牢固,能跟著winter學習是我的幸運,不過在這里要感謝一個大佬的推薦,stormzhang,公眾號也是這個,我的學習榜樣來的,哈哈哈哈哈。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/54953.html
摘要:的碼點被稱為基本字符區域。關于的介紹,我準備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數前不能使用命令,否則會報錯。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完...
摘要:的碼點被稱為基本字符區域。關于的介紹,我準備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數前不能使用命令,否則會報錯。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完...
摘要:二類型執行了但是沒有立即返回,而是先執行了中的覆蓋了中的。普通語句執行后,會得到為的,引擎遇到這樣的,會繼續執行下一條語句。控制類語句分成兩部分對其內部造成影響如。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學習【原文有wint...
摘要:二類型執行了但是沒有立即返回,而是先執行了中的覆蓋了中的。普通語句執行后,會得到為的,引擎遇到這樣的,會繼續執行下一條語句??刂祁愓Z句分成兩部分對其內部造成影響如。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學習【原文有wint...
閱讀 1654·2019-08-30 13:04
閱讀 2205·2019-08-30 12:59
閱讀 1764·2019-08-29 18:34
閱讀 1857·2019-08-29 17:31
閱讀 1255·2019-08-29 15:42
閱讀 3530·2019-08-29 15:37
閱讀 2857·2019-08-29 13:45
閱讀 2771·2019-08-26 13:57