JavaScript數據類型和語法

第一章 類型es6

1.2 內置類型數組

使用 typeof 檢測對象類型並非很是安全的行爲:安全

// 安全的
typeof undefined    // 'undefined'
typeof true         // 'boolean'
typeof 42           // 'number'
typeof '42'         // 'string'
typeof {}           // 'object'
typeof Symbol()     // 'symbol'
typeof (function(){}) // 'function'
// 不安全的
typeof null         // 'object'
typeof []           // 'object'

函數對象能夠擁有屬性。函數的length屬性爲其聲明的參數個數。函數

⚠️spa

  • null 是基本類型中惟一一個「假值」!!!
  • function(函數)也是JavaScript 的一個內置類型。然而查閱規範就會知道, 它其實是 object 的一個「子類型」。具體來講,函數是「可調用對象」,它有一個內部屬 性 [[Call]],該屬性使其能夠被調用(函數不只是對象,還能夠擁有屬性)

1.3 值和類型prototype

JavaScript 中的變量是沒有類型的,只有值纔有。變量能夠隨時持有任何類型的值rest

1.3.1 undefined和undeclaredcode

聲明但尚未賦值的變量是undefined。 尚未在做用域聲明過的變量是undeclared(【嚴格模式】下訪問會拋出ReferenceError)。對象

對於 undeclared(或者 not defined)變量,typeof 照樣返回 "undefined",而且不會報錯,返回'undefined'。索引

或者當其爲全局變量的時候,用window的點操做符去訪問,也不會報錯。

第二章 值

2.1 數組

在稀疏數組中,中間未賦值的內容會初始化爲undefined

var a = [];
a[0] = 1;
a[2] = 3;

a[1]; // undefined
a.length; // 3

⚠️也能夠用鍵訪問(輸入不能轉換爲數字的字符串)去設置數組的屬性,但他們不會歸入數組的值和length,而是做爲獨立的屬性存在。

var arr = [];
  arr[0] = 1;
  arr["2"] = 2;
  arr["obb"] = 3;
  arr.length; // 3
  arr[2]; // 2, 「2」字符串鍵值 被強制轉換爲十進制數字
  arr.obb; arr["obb"]; // 3

類數組(Array Like)(一組經過數字索引的值)

如:DOM查詢返回的DOM元素列表;arguments(es6廢除)

  • 對象表示其類型相似於數組,可是原型鏈上沒有Array對象,天然也沒法直接使用Array的原型方法。
  • 轉換類數組使用ES5的Array.prototype.slice.call(arrayLikeObj),slice() 返回參數列表(上例中是一個類數組)的一個數組複本。或者ES6的Array.from(arrayLikeObj)。

    function foo() {
    var arr = Array.prototype.slice.call( arguments );
    或 var arr = Array.from( arguments );
    arr.push( "bam" );
    console.log( arr );
    }
    foo( "bar", "baz" ); // ["bar","baz","bam"]

2.2 字符串

和數組類似,都有 length 屬性以及 indexOf(..),和 concat(..) 方法

能夠經過「借用」數組的非變動方法來處理字符串:字符串沒有join、map方法

a.join;         // undefined 
a.map;          // undefined 
var c = Array.prototype.join.call( a, "-" ); 
var d = Array.prototype.map.call( a, function(v){     
    return v.toUpperCase() + "."; 
} ).join( "" );

JS中字符串的單個字符不可變,不能用鍵訪問去改變字符串的某個字符。 字符串也能夠借用數組的一些原型方法來進行處理。一個經常使用場景是字符串的倒置:

var c = a
        // 先轉爲Array
        .split('')
        // 再倒置Array
        .reverse()
        // 最後轉回字符串
        .join('');

2.3 數字

直接對數字字面量調用原型方法,有時候須要兩個點(.),這是由於第一個點會被理解爲小數點。 Number.prototype上有這些方法:

  • toExponential(),轉爲指數格式,特別大或小的數字默認用指數格式顯示
  • toFixed(),指定小數位數
  • toPrecision(),指定有效位數的顯示位數
    // 無效語法:
    42.toFixed( 3 ); // SyntaxError ,由於 . 被視爲常量 42. 的一部分
    // 下面的語法都有效:
    (42).toFixed( 3 ); // "42.000"
    0.42.toFixed( 3 ); // "0.420"
    42..toFixed( 3 ); // "42.000"
    其餘進制的問題:
  • 0xf3,16進制
  • 0b11110011,2進制
  • 0o363,8進制

2.3.2 較小的數值

0.1 + 0.2 === 0.3; // false,二進制浮點數中的 0.1 和 0.2 並非十分精確,相加的結果0.30000000000000004

解決方法:偏差範圍值,即機器精度(machine epsilon)。 使用機器精度,能夠判斷兩個浮點值的運算結果是否等於另外一個數字。Math.abs(n1 - n2) < Number.EPSILON

2.3.3 整數安全範圍

安全的最大整數是2^53 - 1,即9007199254740991,ES6中爲Number.MAX_SAFE_INTEGER。同理,最小整數爲其負數-(2^53 - 1),ES6中爲Number.MIN_SAFE_INTEGER。

2.3.4 整數檢測

  • Number.isInteger,檢測是否爲整數
  • Number.isSafeInteger,檢測是否爲安全的整數

2.3.5 32位有符號整數

數位運算符只適用於32位的整數,其餘數位將會被忽略。

2.4 特殊數值

2.4.1 不是值的值

空值:

  • null,指空值,曾經賦值,如今沒有值empty value
  • undefined,指沒有值,從未被賦值,missing value

null 是一個特殊關鍵字,不是標識符,咱們不能將其看成變量來使用和賦值。然而 undefined 倒是一個標識符,能夠被看成變量來使用和賦值。

2.4.2 undefined

經過void運算符能夠返回undefined。

var a = 42; 
console.log( void a, a ); // undefined 4,void 並不改變表達式的結果, 只是讓表達式不返回值:

2.4.3 特殊的數字

  • NaN是一個警惕值,表示數學運算沒有成功,失敗後返回的結果。
    NaN 是一個特殊值,它和自身不相等,是惟一一個非自反 NaN != NaN 爲 true
    ES6 判斷是否爲NaN:Number.isNaN(a)
  • Infinity表示無窮數,數學運算結果溢出
    var a = 1 / 0; // Infinity
    var b = -1 / 0; // -Infinity

    規範規定,若是數學運算(如加法)的結果超出處理範圍,則由 IEEE 754 規範中的「就 近取整」(round-to-nearest)模式來決定最後的結果。
    計算結果一旦溢出爲無窮數(infinity)就沒法再獲得有窮數
  • -0表示第一位正負位爲負,保留了該信息,後續處理的時候會攜帶它。
    對負零進行字符串化會返回 "0"; 若是反過來將其從字符串轉換爲數字,獲得的結果是準確的
    -0 == 0; // true
    -0 === 0; // true

    ⚠️爲何須要負0:保留0的符號位,來獲取方向信息。

2.4.4 特殊等式

ES6:Object.is(..):來判斷兩個值是否絕對相等(用來處理特殊比較,不然使用==或===解)

  • Object.is(NaN, NaN) === true
  • Object.is(+0, -0) === false

2.5 值和引用

簡單值(即基本類型值),經過值複製的方式來賦值/傳遞。 複合值(對象、數組和函數),老是經過引用複製的方式來賦值/傳遞。 減小引用複製反作用的方法是,傳遞時候採用複本建立的方式,好比a.slice()。

slice(..) 不帶參數會返回當前數組的一個淺複本

⚠️標量基本類型值是不可更改的(字符串和布爾也是如此)。

function foo(x) {    
    x = x + 1;    
    x; // 3  
} 
var a = 2; 
var b = new Number( a ); // Object(a)也同樣 
foo( b ); 
console.log( b ); // 是2,不是 3

.......待補充!!

第四章 強制類型轉換

4.1 值類型轉換

顯式值類型轉換稱爲類型轉換,發生在靜態語言的編譯階段。隱式的狀況稱爲強制類型轉換,發生在動態語言的運行時。 JS中只存在強制類型轉換(運行時中轉換),只會返回標量基本類型值,好比字符串、數字和布爾值,不會返回對象或函數。

4.2 抽象值操做

4.2.1 toString

  • null -> 'null'
  • undefined -> 'undefined'
  • true/false -> 'true'/'false'
  • 極大數,極小數 -> 指數形式表達
  • Array -> arr.join(',')
  • Object -> obj.toPrimitive

對於JSON安全:包含undefined、function、symbol和循環引用的對象不符合JSON的結構標準,它們在stringify操做中會被忽略,數組中轉爲null。 當一個對象JSON不安全時,能夠定義其toJSON()方法來返回一個JSON安全的對象,它在JSON.stringify的時候會隱式調用。 JSON.stringify(target, replacer?, space?)的replacer能夠是一個字符串數組或函數,用於指定哪些屬性須要歸入處理。space指定縮進格式。

4.2.2 ToNumber

  • true/false -> 1/0
  • undefined -> NaN
  • null -> 0
  • 對象:調用toPrimitive,首先檢查該值有沒有valueOf()方法,若有則執行,如沒有就使用toString()方法,對最終結果進行強制類型轉換。若是二者均不返回基本類型值,拋出TypeError錯誤。

4.2.3 toBoolean

JS中的假值一般爲基本類型:

  • undefined
  • null
  • false
  • +0, -0, NaN
  • ''(空字符串)

4.3 顯式強制類型轉換

4.3.1 字符串和數字之間的顯式轉換

Number轉String:

  • String(a)
  • a.toString()

String轉Number:

  • Number(b)
  • Number.parseInt(b) / Number.parseFloat(b)
  • +b:注意不要兩個+號連用變成自增,必要時中間加空格。

其餘應用:

  • 日期轉數字(毫秒級時間戳):var d = new Date(); +d;,可是更建議使用其getTime()方法。
  • ~:JS中的取反操做相似於轉換爲數字,而後取-(x+1),經常使用於將-1轉爲0
  • |:後面跟一個toInt32後爲0的值(0,NaN等),能夠起到ToNumber的做用。

4.3.2 顯式解析數字字符串

Number.parseInt()和Number.parseFloat()方法容許字符串中含有非數字字符,遇到非數字字符就中止解析,返回結果。 對於非字符串,會隱式調用其toString()方法。

// 獲得Infinity,解析爲'Infinity',第一個字符I的ASCII碼爲18,因此返回結果是18
// 十進制下返回NaN
Number.parseInt(Infinity, 19);

// toString()解析成了8e-7,返回8
Number.parseInt(0.0000008)

4.3.3 顯式轉換爲布爾值

Boolean()能夠顯式轉換爲布爾值,另外一種方法是用!和!!。 if(...) {}的判斷語句中,若是沒有特別聲明布爾值,就會調用toBoolean()方法。

4.4 隱式強制類型轉換

4.4.2 字符串和數字之間的隱式強制類型轉換

+運算符能用於數字加法,也能用於字符串拼接。它一旦遇到兩邊有一者不是Number的狀況,就會對雙方調用toPrimitive()或toString()方法,而後進行字符串拼接。 -運算符僅用於數字減法,一旦遇到兩邊有一者表示Number的狀況,就會對雙方調用ToNumber()行爲,而後計算減法。

4.4.5 ||和&&

它們的返回值是兩個操做數中的一個。

||:

  • 若是前者判斷爲true,就返回前者,不然返回後者。
  • 相似於a? a:b。
  • 經常使用做空值合併運算符。

&&:

  • 若是前者判斷爲true,就返回後者,不然返回前者。
  • 相似於a? b:a。
  • 經常使用做守護運算符,前面的表達式爲後面把關。好比if(a){ foo(); }能夠改爲a && foo();。

4.4.6 Symbol的強制類型轉換

Symbol只支持顯式強制類型轉換。

var s1 = new Symbol('cool');
String(s1); // 'Symbol(cool)'

s1+ ''; // TypeError

4.5 寬鬆相等和嚴格相等

4.5.2 抽象相等

==容許再相等比較中進行強制類型轉換,===不容許。 特別注意,如下狀況用Object.is()修復:

  1. NaN不等於NaN。
  2. +0等於-0

ES5規範11.9.3.4-5定義:

  1. 若是Type(x)是數字,Type(y)是字符串,則返回 x == ToNumber(y) 的結果。
  2. 若是Type(x)是字符串,Type(y)是數字,則返回 ToNumber(x) == y 的結果。

ES5規範11.9.3.6-7定義:

  1. 若是Type(x)是布爾類型,則返回 ToNumber(x) == y 的結果。
  2. 若是Type(y)是布爾類型,則返回 x == ToNumber(y) 的結果。

可使用a == null來替代a === undefined || a === null。 ES5規範11.9.3.2-3定義:

  1. 若是x爲null,y爲undefined,返回true。
  2. 若是x爲undefined,y爲null,返回true。

ES5規範11.9.3.8-9定義:

  1. 若是Type(x)是字符串或數字,Type(y)是對象,則返回 x == ToPrimitive(y)的結果。
  2. 若是Type(x)是對象,Type(y)是字符串或數字,則返回 ToPrimitive(x) == y的結果。

特殊狀況說明:

'0' == false; // true, Number('0') == Number(false)
false == 0;   // true, Number(false) == 0
false == '';  // true, Number(false) == Number('')
false == [];  // true, Number(false) == ToPrimitive([])
'' == 0;      // true, Number('') == 0
'' == [];     // true, Number('') == ToPrimitive([])
0 == [];      // true, 0 == ToPrimitive([])

4.6 抽象關係比較

比較雙方首先調用ToPrimitive,若是出現非字符串,就根據ToNumber規則將雙方轉換爲數字來比較。若是比較雙方都是字符串,就按字母順序來逐位比較。 須要注意的是,a <= b在JS中被處理成!(b < a)。

第五章 語法

5.1 語句和表達式

JS中,表達式能夠返回一個結果值。

5.1.1 語句的結果值

語句都有一個結果值(undefined也算)。 對於代碼塊,其結果值就如同一個隱式的返回,即返回最後一個語句的結果值。

5.1.2 表達式的反作用

語句系列逗號運算符:在()中寫入多個語句,用逗號','分隔,返回最後一個語句的結果值。 好比b = (a++, a);能夠返回a++以後的a。

5.2 運算符優先級

&&高於||。

相關文章
相關標籤/搜索