最新的 ECMAScript 標準定義了 7 種數據類型:javascript
Undefined類型只有一個值undefined
,表示"缺乏值",就是此處應該有一個值,可是尚未定義。主要的用法:html
(1)變量被聲明瞭,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值爲undefined。
(4)函數沒有返回值時,默認返回undefined。
PS: 值 undefined 並不一樣於未定義的值。可是,typeof 運算符並不真正區分這兩種值。
var i; console.log(i) ; // undefined function f(x){console.log(x)} f(); // undefined var o = new Object(); console.log(o.p); // undefined var func = f(); console.log(func); // undefined console.log(typeof y); //"undefined"
null類型的默認值是null
,從邏輯角度講,是表示一個空對象指針,表示"沒有對象",即該處不該該有值。主要用法:java
(1) 做爲函數的參數,表示該函數的參數不是對象。
(2) 做爲對象原型鏈的終點。
Object.getPrototypeOf(Object.prototype) // null
區別undefined:git
當一個變量聲明後,未初始化,則該值爲undefined,若是這個值是爲了保存對象,則修改其默認初始化的值,改成null。 因此當檢測其類型時,會顯示類型爲object。
typeof null // object (歷史緣由,不是'null') typeof undefined // "undefined" null === undefined // false null == undefined // true null === null // true null == null // true !null // true Number(null) // 0 Number(undefined) // NaN isNaN(1 + null) // false isNaN(1 + undefined) // true
布爾類型,該類型有兩個值:true
false
。Bloolean()函數,能夠將其餘類型的值轉換爲布爾類型。同時也存在隱式類型轉換。es6
這裏區分一下Truthy類型和Falsy類型值。
Falsy類型值包括:""
,0
,null
,undefined
,NaN
,false
。
除了Falsy類型值之外的都被稱爲Truthy類型值,它們會被轉換爲true
。
Boolean(null) // false Boolean('hello') // true Boolean('0') // true Boolean(' ') // true Boolean([]) // true Boolean(function(){}) // true
根據 ECMAScript 標準,JavaScript 中只有一種數字類型:基於 IEEE 754 標準的雙精度 64 位二進制格式的值(-(263 -1) 到 263 -1)。它並無爲整數給出一種特定的類型。除了可以表示浮點數外,還有一些帶符號的值:+Infinity,-Infinity 和 NaN (非數值,Not-a-Number)。
整數能夠用十進制(基數爲10)、十六進制(基數爲16)、八進制(基數爲8)以及二進制(基數爲2)的字面值來表示。json
0, 117 and -345 (十進制, 基數爲10) 015, 0001 and -0o77 (八進制, 基數爲8) 0x1123, 0x00111 and -0xF1A7 (十六進制, 基數爲16或"hex") 0b11, 0b0011 and -0b11 (二進制, 基數爲2)
浮點數(有趣的一點是,在計算前其存儲爲字符串)所佔據的內存空間是整數的兩倍。
語法:[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
segmentfault
3.14 -.2345789 // -0.23456789 -3.12e+12 // -3.12*1012 .1e-23 // 0.1*10-23=10-24=1e-24
NaN:
一、即非數值,是一個特殊的值,這個數值用於表示一個原本要返回數值的操做數,未返回數值的狀況。好比任何數值除以0,本是不符合規範的,js裏,這樣的操做返回NaN
(可是實際上,只有0除以0時返回NaN
,其餘則無窮值)。數組
二、NaN
有兩個不一樣尋常的特色:任何涉及NaN
的操做都會返回NaN
,NaN
值與任何值都不相等,包括自己。
三、isNaN()
函數,這個函數能夠判斷,傳遞的參數是否「不是數值」這裏涉及數值轉換的問題,例如「10」
這個字符串就能夠轉換爲10
,可是「blue」
這個字符串則沒法轉換爲數字,因此isNaN("blue")==true
。安全
+0 === -0 //true 42 / +0; // Infinity 42 / -0; // -Infinity NaN == NaN //false
+Infinity,-Infinity:
要檢查值是否大於或小於 +/-Infinity
,你可使用常量 Number.MAX_VALUE
和 Number.MIN_VALUE
。另外在 ECMAScript 6 中,你也能夠經過 Number.isSafeInteger()
方法還有 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER
來檢查值是否在雙精度浮點數的取值範圍內。 超出這個範圍,JavaScript 中的數字再也不安全了,也就是隻有 second mathematical interger 能夠在 JavaScript 數字類型中正確表現。app
這個算是比較熟悉的了這裏引用一下MDN的描述。
JavaScript的字符串類型用於表示文本數據。它是一組16位的無符號整數值的「元素」。在字符串中的每一個元素佔據了字符串的位置。第一個元素的索引爲0,下一個是索引1,依此類推。字符串的長度是它的元素的數量。
不一樣於類 C 語言,JavaScript 字符串是不可更改的。這意味着字符串一旦被建立,就不能被修改。可是,能夠基於對原始字符串的操做來建立新的字符串。
主要強調一下ES2015的模板字符串:
// Basic literal string creation `In JavaScript '\n' is a line-feed.` // Multiline strings `In JavaScript this is not legal.` // String interpolation var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?` // Construct an HTTP request prefix is used to interpret the replacements and construction POST`http://foo.org/bar?a=${a}&b=${b} Content-Type: application/json X-Credentials: ${credentials} { "foo": ${foo}, "bar": ${bar}}`(myOnReadyStateChangeHandler);
String()
函數能夠將任何類型的值轉換爲字符串,包括null
轉換爲'null'
、undefined
轉換爲'undefined'
。
語法:Symbol([description])
一、每一個從Symbol()返回的symbol值都是惟一的。
直接使用Symbol()建立新的symbol類型,並用一個字符串(可省略)做爲其描述。如下代碼建立了三個新的symbol類型。 字符串 「foo」 的做用僅爲描述,它每次都會建立一個新的 symbol類型:
var sym1 = Symbol(); var sym2 = Symbol('foo'); var sym3 = Symbol('foo'); Symbol("foo") === Symbol("foo"); // false
還可使用Symbol.for
方法建立新的symbol類型,和前者區別Symbol.for()
會把symbol值以一個key值登記到全局環境中,Symbol()
就不會。Symbol.for()
不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key是否已經存在,若是不存在纔會新建一個值。好比,若是你調用Symbol.for("cat")
30 次,每次都會返回同一個 Symbol 值,可是調用Symbol("cat")
30 次,會返回 30 個不一樣的 Symbol 值。查看登記的Symbol值可使用Symbol.keyFor
方法,該方法返回一個已登記的 Symbol 類型值的key。
let sym1 = Symbol('foo'); let sym2 = Symbol('foo'); let sym3 = Symbol.for('foo'); let sym4 = Symbol.for('foo'); sym1 === sym2 //false sym3 === sym4 //true Symbol.keyFor(sym1) //undefined Symbol.keyFor(sym3) //"foo"
二、 再也不支持new 運算符的語法:
var sym = new Symbol(); // TypeError
這會阻止建立一個顯式的 Symbol 包裝器對象而不是一個 Symbol 值。圍繞原始數據類型建立一個顯式包裝器對象從 ECMAScript 6 開始再也不被支持。 然而,現有的原始包裝器對象,如 new Boolean、new String以及new Number由於遺留緣由仍可被建立。
三、特殊的類型轉換
Symbol 值不能與其餘類型的值進行運算。
Symbol 值能夠顯式轉爲字符串、布爾值,可是不能轉爲數值。
四、用於對象屬性名(主要)
Symbol 值做爲對象屬性名時,不能用點運算符。通常經過方括號結構和Object.defineProperty
,將對象的屬性名指定爲一個 Symbol 值。
let sym1 = Symbol(); let sym2 = Symbol(); let sym3 = Symbol(); let a = { [sym1]: 'Symbol1'; }; a[sym2] = 'Symbol2'; Object.defineProperty(a, sym3, { value: 'Symbol3' }); a.sym1 = 'Hello!'; a[sym1] // "Symbol1" a['sym1'] // "Hello!"
Symbol 做爲屬性名,該屬性不會出如今for...in
、for...of
循環中,也不會被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。可是,它也不是私有屬性,有一個Object.getOwnPropertySymbols
方法,返回一個數組,成員是當前對象的全部用做屬性名的 Symbol 值。
更多的Symbol相關內容參考這篇文章—— 傳送門
在計算機科學中, 對象是指內存中的能夠被標識符引用的一塊區域。
對象屬於複雜數據類型,也能夠說是引用類型(邏輯上等價於class/類)。相對於原始數據類型的直接存取(棧內存),複雜數據類型的存儲方式爲引用(堆內存,棧內存保存對應的指針)。
ECMAScript 中的全部對象都由這個對象繼承而來,Object 對象中的全部屬性和方法都會出如今其餘對象中,因此理解了 Object 對象,就能夠更好地理解其餘對象。
本文主要介紹如下幾點:
一、Object()與new Object()
Object函數能夠把任意值轉換爲對象;new Object()
則是生成新對象,能夠簡寫爲{}
。除語義上的不一樣外,二者的用法相同,如下以Object()
爲例:
var obj = Object(); var obj = Object(undefined); var obj = Object(null); //以上語句等效,返回空對象 obj instanceof Object // true var obj = Object(1); obj instanceof Object // true obj instanceof Number // true var obj = Object('foo'); obj instanceof Object // true obj instanceof String // true var obj = Object(true); obj instanceof Object // true obj instanceof Boolean // true
若是參數原本就是一個對象便不須要轉換,直接返回該對象:
var arr = []; var obj = Object(arr); // 返回原數組 obj === arr // true var value = {}; var obj = Object(value) // 返回原對象 obj === value // true var fn = function () {}; var obj = Object(fn); // 返回原函數 obj === fn // true
二、Object靜態方法
所謂「靜態方法」,是指部署在Object對象自身的方法。例如:Object.key = value
、{key:value}
。
通常使用Object.keys
方法和Object.getOwnPropertyNames
方法來遍歷對象的屬性。區別在於後者能夠列舉不可枚舉的屬性名,例如數組的length
。
var a = ['Hello', 'World']; Object.keys(a) // ["0", "1"] Object.getOwnPropertyNames(a) // ["0", "1", "length"]
其餘靜態方法:(傳送門)
1)對象屬性模型的相關方法
Object.getOwnPropertyDescriptor()
:獲取某個屬性的描述對象。Object.defineProperty()
:經過描述對象,定義某個屬性。定義key爲Symbol的屬性的方法之一。Object.defineProperties()
:經過描述對象,定義多個屬性。2)控制對象狀態的方法
Object.preventExtensions()
:防止對象擴展。Object.isExtensible()
:判斷對象是否可擴展。Object.seal()
:禁止對象配置。Object.isSealed()
:判斷一個對象是否可配置。Object.freeze()
:凍結一個對象。Object.isFrozen()
:判斷一個對象是否被凍結。3)原型鏈相關方法
Object.assign(target, ...sources)
:用於將全部可枚舉屬性的值從一個或多個源對象複製到目標對象。它將返回目標對象。Object.create()
:該方法能夠指定原型對象和屬性,返回一個新的對象。Object.getPrototypeOf()
:獲取對象的Prototype
對象。三、Object實例方法
定義在Object.prototype
的·對象稱爲實例方法,全部Object的實例對象都繼承了這些方法。Object
實例對象的方法,主要有如下六個。
Object.prototype.valueOf()
:返回當前對象對應的值。Object.prototype.toString()
:返回當前對象對應的字符串形式。檢測對象類型。 Object.prototype.toLocaleString()
:返回當前對象對應的本地字符串形式。Object.prototype.hasOwnProperty()
:判斷某個屬性是否爲當前對象自身的屬性,仍是繼承自原型對象的屬性。Object.prototype.isPrototypeOf()
:判斷當前對象是否爲另外一個對象的原型。Object.prototype.propertyIsEnumerable()
:判斷某個屬性是否可枚舉。之因此會說到這個判斷問題,主要緣由是typeof
是不太靠譜的。首先JavaScript是動態數據類型的語言,不少類型檢查是沒必要要的。在具體實現上的問題,在實際的項目應用中,typeof
也只有兩個用途,就是檢測一個元素是否爲undefined
,或者是否爲function
。由下面的表格可見一斑:
Value function typeof ------------------------------------- "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object new RegExp("meow") RegExp object {} Object object new Object() Object object
若是仍是要判斷的話,公認的靠譜解法是 Object.prototype.toString.call(x) === '[object type]'
。具體實現能夠參考jQuery.type()
源碼。另外經過構造函數建立的對象均可以用 instanceof
檢查。