基本介紹
ECMAScirpt 5.1 中定義了6種數(shù)據(jù)類型,其中有5中簡單數(shù)據(jù)類型(基本數(shù)據(jù)類型):
- Undefined:只有一個值,為undefined,意味著“空值(no value)”,適用于所有數(shù)據(jù)類型。
- Null:只有一個值,為null,意味著“空對象(no object)”,只適用于對象類型。(literal)
- Boolean:有兩個值,為true與false
- Number:值遵循IEEE 754標(biāo)準(zhǔn)的64位浮點數(shù)的集合,沒有整型數(shù)據(jù)結(jié)構(gòu)。此外還包含三個特殊的值:NaN、Infinity、Infinity
- String:值是有窮個Unicode字符的集合。必須用'或"括起來。
- 還有一種復(fù)雜數(shù)據(jù)類型: Object
- 最新的ECMAScript 6 又加了一種類型:Symbol (ECMAScript 6 新定義)
typeof操作符
用來檢測給定變量的數(shù)據(jù)類型。
對一個值使用typeof操作符可能返回下列某個字符:
- “undefined”值未定義
- “boolean”布爾值
- “string”字符串
- “number”數(shù)值
- “object”對象或null
- “function”函數(shù)
使用:typeof 操作數(shù) / typeof(操作數(shù)) ——>圓括號不是必須的,因為typeof不是函數(shù)
Undefine類型
首字母大寫的Undefined表示的是一種數(shù)據(jù)類型,小寫的undefined表示的是屬于這種數(shù)據(jù)類型的唯一的一個值。
使用var聲明變量但未進(jìn)行初始化時,這個變量的值就是undefined,例如:
var message;
alert(message == undefined); // true
一個未初始化的變量的值為undefined,一個沒有傳入實參的形參變量的值為undefined,如果一個函數(shù)什么都不返回,則該函數(shù)默認(rèn)返回undefined。
注意: 對未聲明的變量執(zhí)行typeof操作符同樣會返回undefined。
var message; //這個變量聲明之后默認(rèn)為undefined
// 下面這個變量未聲明
// var age
alert(typeof message); // "undefined"
alert(typeof age); // "undefined"
Null類型
首字母大寫的Null表示的是一種數(shù)據(jù)類型,小寫的null表示的是屬于這種數(shù)據(jù)類型的唯一的一個值。
null值表示一個空對象指針:
var car = null;
alert(typeof car); //"object"
如果定義的變量準(zhǔn)備用于保存對象,那么最好將該變量初始化為null。
undefined 值派生自 null,因此規(guī)定相等性測試返回 true。
null == undefined // true
null === undefined // false
null 是一個字面量 (而不是全局對象的一個屬性,undefined 是 )
console.log(null); //null
console.log(undefined); //undefined
console.log(window.null); //undefined
console.log(window.undefined); //undefined
null與undefined的區(qū)別
console.log(foot); // Uncaught ReferenceError: foot is not defined
var foo;
console.log(foo); // undefined
var bar = null;
console.log(bar); // null
typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
Boolean類型
1、如果 Boolean 構(gòu)造函數(shù)的參數(shù)不是一個布爾值,則該參數(shù)會被轉(zhuǎn)換成一個布爾值。
2、轉(zhuǎn)換規(guī)則:
| 數(shù)據(jù)類型 | true | false |
|---|---|---|
| Boolean | true | false |
| String | 任何非空字符串 | ""(空字符串) |
| Number | 任何非零數(shù)字值(包括無窮大) | 0 和 NaN |
| Object | 任何對象 | null |
| Undefined | (不適用) | undefined |
//初始化的時候
//false
var bfalse = new Boolean(false);
var bEmptyString = new Boolean("");
var bZero = new Boolean(0);
var bNaN = new Boolean(NaN);
var bNull = new Boolean(null);
var bNoParam = new Boolean(); //相當(dāng)于傳入undefined
//true
var btrue = new Boolean(true);
var btrueString = new Boolean("true");
var bfalseString = new Boolean("false");
var bSuLin = new Boolean("Su Lin");
不要通過新建 Boolean 對象的方法來將一個非布爾值轉(zhuǎn)化成布爾值。 直接使用 Boolean 函數(shù)才是正確的
var x = Boolean(expression); // 這樣用
var x = new Boolean(expression); // 而不要這樣!
Number類型
根據(jù) ECMAScript 標(biāo)準(zhǔn),JavaScript 中只有一種數(shù)字類型:基于 IEEE 754 標(biāo)準(zhǔn)的雙精度 64 位二進(jìn)制格式的值(-(253 -1) 到 253 -1)。它并沒有為整數(shù)給出一種特定的類型。除了能夠表示浮點數(shù)外,還有一些帶符號的值:+Infinity,-Infinity 和 NaN (非數(shù)值,Not-a-Number)
1.數(shù)值字面量格式:
var intNum = 55; //十進(jìn)制整數(shù)
var octalNum1 = 070; //八進(jìn)制 56
var octalNum1 = 079; //無效,解析為79
var octalNum1 = 08; //無效,解析為8
var hexNum1 = 0xA; //十六進(jìn)制 10
var hexNum1 = 0x1f; //十六進(jìn)制31
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; //有效但不推薦
var floatNum4 = 1.0; //小數(shù)點后面沒有數(shù)字,轉(zhuǎn)換為整數(shù) 解析為1
var floatNum5 = 10.0; //整數(shù) 解析為10
var floatNum6 = 3.125e7; //等于31250000
數(shù)字類型只有一個整數(shù),它有兩種表示方法: 0 可表示為 -0 和 +0("0" 是 +0 的簡寫)。 在實踐中,這也幾乎沒有影響。 例如 +0 === -0 為真。 但是,你可能要注意除以0的時候:
42 / +0; // Infinity
42 / -0; // -Infinity
2.數(shù)值范圍
| 表示 | 描述 |
|---|---|
| Number.MIN_VALUE | 最小數(shù)值,一般為5e-324 |
| Number.MAX_VALUE | 最大數(shù)值,一般為1.7976931348623157e+308 |
| Infinity | 正無窮,是不能參與計算的數(shù)值 |
| -Infinity | 負(fù)無窮,是不能參與計算的數(shù)值 |
3.NAN
如果參數(shù)無法被轉(zhuǎn)換為數(shù)字,則返回 NaN。
- 任何涉及NaN的操作(例如NaN/10)都會返回NaN。
- NaN與任何值都不相等,包括NaN本身。
ECMAScript定義了isNaN()函數(shù)來確定某個參數(shù)是否“不是數(shù)值”。isNaN()在接收到一個值之后,會嘗試將這個值轉(zhuǎn)換為數(shù)值。某些不是數(shù)值的值會直接轉(zhuǎn)換為數(shù)值,而任何不能被轉(zhuǎn)換為數(shù)值的值都會導(dǎo)致這個函數(shù)返回true。
isNaN(NaN); // true
isNaN(Number.NaN); // true
isNaN(0 / 0) // true
// e.g. these would have been true with global isNaN()
Number.isNaN("NaN"); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
Number.isNaN("blabla"); // false
// These all return false
Number.isNaN(true);
Number.isNaN(null);
Number.isNaN(37);
Number.isNaN("37");
Number.isNaN("37.37");
Number.isNaN("");
Number.isNaN(" ");
將非數(shù)值轉(zhuǎn)換為數(shù)值:Number()、parseInt()、parseFloat()
Number() 可用于任何數(shù)據(jù)類型
轉(zhuǎn)換規(guī)則:
- Boolean值:true false分別轉(zhuǎn)換為1 0
- 數(shù)字值:簡單的傳入和返回
- null值:0
- undefined值:返回NaN
- 字符串:
- 只包含數(shù)字(包括前面帶正、負(fù)號)則轉(zhuǎn)換為十進(jìn)制數(shù)值
- 包含有效的浮點格式,如“1.1”,則轉(zhuǎn)換為對應(yīng)的浮點數(shù)
- 包含有效的十六進(jìn)制格式,如“0xf”,則轉(zhuǎn)換為相同大小的十進(jìn)制整數(shù)
- 字符串為空,則轉(zhuǎn)換為0
- 字符串中包含除上述格式之外的字符,則轉(zhuǎn)換為NaN
- 若為對象,則調(diào)用對象的valueof()方法,然后依照前面的規(guī)則轉(zhuǎn)換返回值。若轉(zhuǎn)換的結(jié)果是NaN,則調(diào)用對象的toString()方法,然后再次依照前面的規(guī)則轉(zhuǎn)換返回值。
var num1 = Number("hello world!"); //NaN
var num2 = Number(""); //0
var num3 = Number("000011"); //11
var num4 = Number(true); //1
//處理整數(shù)常用parseInt()函數(shù)
var num1 = parseInt("1234blue"); //1234
var num2 = parseInt(""); //NaN
var num3 = parseInt("0xA"); //10
var num4 = parseInt(22.5); //22
var num5 = parseInt("070"); //ECMAScript 3 認(rèn)為是56 八進(jìn)制,ECMAScript 5 認(rèn)為是70 十進(jìn)制
var num6 = parseInt("70"); //70 十進(jìn)制
var num7 = parseInt("0xf"); //15
//處理浮點數(shù)常用parseFloat()函數(shù)
var num1 = parseFloat("1234blue"); //1234
var num3 = parseFloat("0xA"); //0
var num4 = parseFloat("22.5"); //22.5
var num5 = parseFloat("22.34.5"); //22.34
var num6 = parseFloat("0908.5"); //908.5
var num7 = parseFloat("3.125e7"); //31250000
String類型
1、JavaScript的字符串類型用于表示文本數(shù)據(jù)。它是一組16位的無符號整數(shù)值的“元素”。
2、在字符串中的每個元素占據(jù)了字符串的位置。第一個元素的索引為0,下一個是索引1,依此類推。字符串的長度是它的元素的數(shù)量
3、與 C 語言不同,JavaScript 中字符串是不可變的(譯注:如,JavaScript 中對字符串的操作一定返回了一個新字符串,原始字符串并沒有被改變)
Javascript中一切都是object-based。
創(chuàng)建string,也有兩種類型
- 使用字面量方式創(chuàng)建的字符串,為基本類型的 string
- 實際上保存就是的值,是一個基本類型
- 使用String()創(chuàng)建的字符串,為基本類型的 string
- 使用構(gòu)造函數(shù) new String()的方式創(chuàng)建的字符串,為對象類型的 string
- 實際上保存的是一個指向字符串對象的指針
轉(zhuǎn)換為字符串
- 第一種方法:toString() 返回相應(yīng)值的字符串表現(xiàn)(null與undefined值沒有這個方法)
- 第二種方法:在不知道轉(zhuǎn)換的值是不是null或undefined情況下,可以用轉(zhuǎn)型函數(shù)String(),能將任何類型的值轉(zhuǎn)換為字符串。
Object類型
數(shù)據(jù)和功能的集合。是所有對象的基礎(chǔ),所有對象都具有Object的基本屬性和方法。
var o = new Object();
var o = new Object; // 有效,但不推薦省略圓括號
①constructor屬性
構(gòu)造函數(shù)屬性,可確定當(dāng)前對象的構(gòu)造函數(shù)。
var o = new Object();
console.log(o.constructor == Object);//true
var arr = new Array();
console.log(arr.constructor == Array);//true
②hasOwnProperty(propertyName)
判斷屬性是否存在于當(dāng)前對象實例中(而不是在實例的原型中)。
③isPrototypeOf(object)
判斷傳入的對象是否是當(dāng)前對象的原型
④propertyIsEnumerable(propertyName)
判斷給定的屬性是否能使用for-in語句來枚舉
⑤toLocaleString()
返回對象的字符串表示,該字符串與執(zhí)行環(huán)境的地區(qū)對應(yīng)
⑥toString()
返回對象的字符串表示
⑦valueOf()
返回對象的字符串、數(shù)值或布爾值表示
Symbol類型
ES6引入了一種新的原始數(shù)據(jù)類型Symbol,表示獨一無二的值。 可以從根本上防止屬性名的沖突。
Symbol值通過Symbol函數(shù)生成。這就是說,對象的屬性名現(xiàn)在可以有兩種類型,一種是原來就有的字符串,另一種就是新增的Symbol類型。凡是屬性名屬于Symbol類型,就都是獨一無二的,可以保證不會與其他屬性名產(chǎn)生沖突。
let s = Symbol();
typeof s // "symbol"
上面代碼中,變量s就是一個獨一無二的值。typeof運算符的結(jié)果,表明變量s是 Symbol 數(shù)據(jù)類型,而不是字符串之類的其他類型。
注意, Symbol 函數(shù)前不能使用 new 命令,否則會報錯。這是因為生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由于 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似于字符串的數(shù)據(jù)類型。
Symbol函數(shù)可以接受一個字符串作為參數(shù),表示對 Symbol 實例的描述,主要是為了在控制臺顯示,或者轉(zhuǎn)為字符串時,比較容易區(qū)分。
var s1 = Symbol('foo');
var s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
上面代碼中,s1和s2是兩個 Symbol 值。如果不加參數(shù),它們在控制臺的輸出都是Symbol(),不利于區(qū)分。有了參數(shù)以后,就等于為它們加上了描述,輸出的時候就能夠分清,到底是哪一個值。
注意,Symbol 函數(shù)的參數(shù)只是表示對當(dāng)前 Symbol 值的描述,因此相同參數(shù)的 Symbol 函數(shù)的返回值是不相等的。
// 沒有參數(shù)的情況
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
// 有參數(shù)的情況
var s1 = Symbol("foo");
var s2 = Symbol("foo");
s1 === s2 // false
上面代碼中,s1和s2都是Symbol函數(shù)的返回值,而且參數(shù)相同,但是它們是不相等的。
由于每一個Symbol值都是不相等的,這意味著Symbol值可以作為標(biāo)識符,用于對象的屬性名,就能保證不會出現(xiàn)同名的屬性。這對于一個對象由多個模塊構(gòu)成的情況非常有用,能防止某一個鍵被不小心改寫或覆蓋。Symbol值作為對象屬性名時,不能用點運算符。在對象的內(nèi)部,使用Symbol值定義屬性時,Symbol值必須放在方括號之中。
var mySymbol = Symbol();
// 第一種寫法
var a = {};
a[mySymbol] = 'Hello!';
// 第二種寫法
var a = {
[mySymbol]: 'Hello!'
};
// 第三種寫法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上寫法都得到同樣結(jié)果
a[mySymbol] // "Hello!"
Symbol 值不能與其他類型的值進(jìn)行運算,會報錯。
var 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
但是, Symbol 值可以顯式轉(zhuǎn)為字符串。
var sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'
Symbol.for() , Symbol.keyFor()
有時,我們希望重新使用同一個 Symbol 值,Symbol.for方法可以做到這一點。它接受一個字符串作為參數(shù),然后搜索有沒有以該參數(shù)作為名稱的Symbol 值。如果有,就返回這個 Symbol 值,否則就新建并返回一個以該字符串為名稱的 Symbol 值。
var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo');
s1 === s2 // true
上面代碼中, s1 和 s2 都是 Symbol 值,但是它們都是同樣參數(shù)的Symbol.for方法生成的,所以實際上是同一個值。
Symbol.for()與Symbol()這兩種寫法,都會生成新的 Symbol 。
區(qū)別:
前者會被登記在全局環(huán)境中供搜索,后者不會。
- Symbol.for()不會每次調(diào)用就返回一個新的 Symbol 類型的值,而是會先檢查給定的 key 是否已經(jīng)存在,如果不存在才會新建一個值。比如,如果你調(diào)用
Symbol.for("cat") 30次,每次都會返回同一個 Symbol 值,但是調(diào)用Symbol("cat") 30 次,會返回 30 個不同的 Symbol 值。
Symbol.for("bar") === Symbol.for("bar")
// true
Symbol("bar") === Symbol("bar")
// false
上面代碼中,由于Symbol()寫法沒有登記機制,所以每次調(diào)用都會返回一個不同的值。
- Symbol.keyFor 方法返回一個已登記的 Symbol 類型值的 key 。
var s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
var s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
上面代碼中,變量s2屬于未登記的 Symbol 值,所以返回undefined。
需要注意的是,Symbol.for為 Symbol 值登記的名字,是全局環(huán)境的,可以在不同的 iframe 或 service worker中取到同一個值。