JavaScript 系列博客(二)

JavaScript 系列博客(二)

前言

本篇博客介紹 js 中的運算符、條件語句、循環語句以及數組。javascript

運算符

  • 算術運算符
// + | - | * | / | % | ++ | --
    console.log(5 / 2);  // 2.5
    // 取整
    console.log('%d', 5 / 2); // "2"
    var num = parseInt(5 / 2);  // 2
    console.log(num);

    // 取模(求餘)
    console.log(5 % 2);  // 1
    // 任何一個天然數對 n 取餘, 結果爲 [0, n-1]

    // 自增|自減 ++|--
    // ++就是自增1, --就是自減1
    var num = 10
    console.log(num++);  // 10
    console.log(++num);  // 12
    console.log(num);  // 12
    // ++在變量後(num++), 先將變量的值拿去使用,再自身自增1
    // ++再變量前(++num), 先將變量自身自增1, 再將結果拿去使用
    // 總結: 無論++在前在後,運算結束後,變量自身值必定自增1

    // res = ++num  <==>  num++; res = num
    // res = num++  <==>  res = num; ++num
  • 賦值運算符
// = | += | -= | *= | /= | %=
    var x = 10;  // 將10的值賦值給變量x
    y = x;  // 將變量x的值傳遞給變量y
    console.log(y);  // 10

    x += 10;  // x = x + 10, 運算方式由右至左, 將x+10的結果從新複製給x
    console.log(y);  // 10, y的值雖然來源於x, 但y值只由自身控制

    // x /= 10  == x = x / 10
  • 比較運算符
// 比較運算符, 結果爲Boolean類型
    // == | ===
    console.log("5" == 5);  // true, 只作值比較
    console.log("5" === 5);  // false, 比較值及類型

    // != | !==
    console.log("5" != 5);  // false, 只作值比較
    console.log("5" !== 5);  // true, 比較值及類型
  • 邏輯運算符
// 總結&&: 全真爲真, 有假則假
    // 總結||: 全假則假, 有真則真
    // 總結!: 真則假, 假則真

    // 邏輯運算符的結果本質上爲表達式值
    // 表達式: 由數字,變量,運算符組成的合法式子
    res = a < b && c;
    console.log(res);

    res = (a = 1 || b == c);
    console.log(res);

    // 針對 && | ||
    // 疑問: 邏輯運算符結果可能爲邏輯運算符以前表達式的值,也多是以後表達式的值

針對邏輯運算符,會出現短路現象。當運算符爲&&時,若是第一個表達式的結果爲假,那麼第二個表達式就不會執行;同理,||當第一個表達式的結果爲真時,第二個表達式就不會執行(python 在邏輯判斷也會出現短路現象)html

  • 三目運算符(等同於 python 中的三元表達式)
// 語法:  條件表達式 ? 表達式1 : 表達式2
    var a = 10, b = 20;
    var res = a < b ? a : b;  // 取小值
    console.log(res);
    res = a < b ? b : a;  // 取大值
    console.log(res);

    // 相似於if...esle...
    a < b ? console.log("表達式結果爲true") : console.log("表達式結果爲false")

三目表達式能夠看作 if...else 的簡寫形式。java

程序結構

根據執行方式程序能夠分爲三大結構:順序結構、分支結構、循環結構。其實只有一種結構就是順序結構,像分支結構本質仍是順序執行的,只不過選擇多了;而循環結構也是同樣的道理。python

條件語句

if 結構

if結構首先判斷後面表達式的布爾值,而後決定是否執行後面的代碼。布爾值只有兩個,true 爲真,false 爲假。數組

// 語法
if (表達式1) {
	語句; };
// 或
if (表達式2) {語句};

上面是 if 結構的基本形式。須要注意的是,‘’布爾值‘’每每是由一個條件表達式產生的,必須放在圓括號中,表達對該表達式求值。若是表達式的結果爲 true,就執行後面的代碼語句;若是爲 false,則跳事後面的語句。數據結構

if...else 結構

跟 python 同樣,if 後面也能夠跟 else 代碼塊,表示不知足條件時,要執行的代碼塊。函數

if (表達式3) {
    //表達式結構爲真時,執行的代碼
} else {
    // 表達是結構爲假時,執行的代碼
}

若是須要對於一個表達式進行屢次判斷時,多個 if...else 語句能夠連到一塊兒。spa

if (表達式4) {
    
} else if {表達式5} {
    
} else if {表達式6} {
    
} else {
    
} // 注意:else 代碼塊老是與離本身最近的那個 if 語句配對

switch 分支

// 語法
switch (結果爲整數|字符串的表達式) {
            case 值1(值須要和表達式進行類型統一): 代碼塊; break;
            ...
            case 值n: 代碼塊; break;
            default: 代碼塊;
        }
// 須要注意的是,switch 語句後面的表達是,與 case 語句後面的表達是比較運行結果時,採用的是嚴格相等運算符(===),而不是相等運算符(==),這意味着比較時不會發生類型轉換。
// break做用是結束分支結構(結束所屬switch語句),能夠省略。

default 分支

default分支,出如今全部case之下,當全部case沒有匹配上,走該分支,該分支也能夠省略,表明沒有未匹配到的動做。設計

循環語句

循環語句用於重複執行某個操做,直到條件不知足跳出循環。code

while 循環

while 循環包括一個循環條件和一段代碼塊,只要條件爲真,就會不斷執行代碼塊。

while (條件表達式) {
    語句;
}

while語句的循環條件爲一個條件表達式,必須放在圓括號中,表示須要先計算表達式的結果才能進行是否進行循環。代碼塊部分,若是隻有一條語句,能夠省略大括號。

var i = 0;
while (i < 100) {
    console.log('i 爲:' + i);
    i++;
}

這段代碼會循環100次,直到i 等於100。

for 循環

for 循環是循環結構的另外一種形式,能夠指定循環的起點、終點和終止條件。格式以下:

/*
    for (循環變量定義並初始化①; 循環變量條件表達式②; 循環變量增量③) {
        代碼塊④;
    }
    執行順序 ① ②④③ ... ②④③ ②, ②④③個數就是循環次數
     */

    for (var i = 0; i < 5; i++) {
        console.log("我最棒, 我最帥, 我是天下第一!");
    }

上段代碼圓括號裏面有三個表達式:

  • 表達式①(initialize):肯定循環變量的初始值,只在循環開始時執行一次。
  • 表達式②(test):每輪循環開始時,都須要執行判斷,只有判斷爲真時,纔會繼續循環。
  • 表達式③(increment):每輪循環的最後一個操做,一般用來遞增循環變量。

全部 for 循環,均可以用 while 循環實現。

for 循環裏面的三個表達式能夠省略其中任何一個,也能夠所有省略。

for ( ; ; ) {
    console.log('Hello MUSIBII!');
}

這段代碼省略了 for 表達式的三個部分,結果就致使了一個無限循環。

do...while 循環

do...while 循環和 for 循環相似,惟一區別就是 do 循環無論條件滿不知足都會執行一次循環,以後進行第二次循環纔會進行判斷條件。

do 
    代碼塊
while (條件表達式);

// 或
do {
    代碼
} while (條件表達式);

無論條件是否爲真,do...while 循環至少須要運行一次,這是和while 循環的本質區別。另外 while 語句後面的分號不要省略。

var x = 3;
var y = 0;
do {
    console.log(y);
    y++;
} while(y < x);

break 和 continue 語句

只要有循環就少不了 break 和 continue,這兩個關鍵詞都具備跳轉做用,能夠控制代碼的執行順序。

  • break 語句用於跳出循環體
var i = 0;

while(i < 100) {
    console.log('i 爲:' +i);
    i++;
    if (i === 10) break;
}

當 i 等於10時,if 表達式判斷爲真,執行 break 跳出循環體

  • continue 語句用於當即終止本輪循環,進入下次循環。
var i = 0;
while(i < 100) {
    if (i % 2 === 0) continue;
    console.log('i 爲:' +i);
    i++;
}

這段代碼只有 i 爲奇數時,纔會輸出 i 的值。若是 i 爲偶數,則直接進入下一輪循環。若是存在多重循環,不帶參數的 break 語句和 continue 語句都只針對本層循環。

數組

數組的定義

數組(Array)是按照次序排列的一組值。每一個值得索引從0開始,數組使用中括號表示。

var array = ['a', 'b', 'c', 1, 2, 3];

這樣,array 就構成一個數組,兩端的方括號是數組的標誌。'a' 是0號位置,3是5號位置。

除了在定義時賦值,數組也能夠先定義後賦值。(經過構造函數(constructor))

var array = [];
array[0] = 'hello';
array[1] = 'world';

任何類型的數據,均可以放入數組(類比 python 的列表)。

特別的,若是數組的元素仍是數組,則造成了多維數組。

數組的本質

本質上,數組是對象類型的一種,typeof 運算符會返回數組的類型爲 object。

typeof(['a', 'b', 'c']) // object

這代表,數組類型爲對象。數組的特殊性體如今,它的鍵名是按次序排列的一組整數(從0開始)。

var array = ['a', 'b', 'c'];

Object.keys(array) // ['0', '1', '2']

經過 Object 的 keys 方法能夠返回指定數組的全部鍵名。

因爲數組成員的鍵名是固定的,所以數組不用爲每一個元素指定鍵名,而對象的每一個成員都必須指定鍵名。JavaScript 語言規定,對象的鍵名一概爲字符串,因此,數組的鍵名其實也是字符串。之因此能夠用數值取值,是由於非字符串的鍵名會被轉爲字符串。

var array = ['a', 'b', 'c'];

array[0]; // 'a'
array['0']; // 'a'

這點在賦值時也會成立(js 的數據類型轉換須要注意),一個值老是先轉成字符串,再進行賦值。

var a = [];
a[1.00] = 'c';
a[1]; // 'c'

賦值時,先把1.00轉爲字符串1,賦值結束後能夠經過數字鍵1取值。

length 屬性

數組的 length 屬性返回數組的成員數量。

array.length // 3

JavaScript 使用一個32位整數,保存數組的元素個數。這意味着,數組成員最多隻用(2^32 - 1)個,也就是說 length 屬性的最大值就是4294967295。

只要是數組就必定有 length 屬性。該屬性是一個動態的值(由於能夠動態賦值)。數組的數字鍵不須要連續,length 屬性的值老是比最大的那個整數鍵大1.另外,數組是一種動態的數據結構,能夠隨時增減數組成員。

注意:length 屬性是可寫的。若是認爲的設置一個小於當前成員個數的值,該數組的成員會自動減小到 length 設置的值。

var array = ['a', 'b', 'c'];
array.length; // 3
array.length = 2;
array // ['a', 'b']

這代表當數組的 length 屬性值設爲2,那麼整數鍵2就會被刪除。這樣清空一個數組就能夠直接把 length 屬性值設爲0就 ok 了。

若是人爲設置 length 值大於當前數組元素個數,那麼數組的成員數量會增長到這個值,新增的位置都是空(undefined)。

var array = ['a'];

a.length = 2;
a[1]; // undedined

當 length 屬性值設爲大於數組個數時,讀取新增的位置都會返回 undefined。若是設置的不合法,好比設置一個非整數的值時,JavaScript 會報錯。

var array = [];
array.length = -1;
// RangeError: Invalid array length

array.length = Math.pow(2, 32);
// RangeError: Invalid array length

array.length = 'abc';
// RangeError: Invalid array length

由於數組的本質是一種對象,因此能夠爲數組添加屬性,可是這不會影響數組的 length 屬性。

var array = ['a'];
array['name'] = 'musibii';

array.length; // 1

注意:若是數組添加的鍵名超過範圍的數值,該鍵名會自動轉化爲字符串。

var array = [];
array[-1] = 'a';

array[Math.pow(2, 32)] = 'b';

array.length //0
array[-1]; // 'a'
array[4294967296]; // 'b'

上面爲數組添加了兩個不合法的數字鍵,並不會影響到 length 的值。這些數字鍵都變成了字符串鍵名。最後兩行會取到值是由於會把數字轉爲字符串。

in 運算符

檢查某個鍵名是否存在於數組中,使用 in 運算符,這個適用於對象,天然也適用於數組。

var array = ['a', 'b', 'c', 1, 2, 3];
2 in array; // true
'2' in array; // true
6 in array; // false

數組存在鍵名爲2的鍵,因爲鍵名都爲字符串,因此數值2會自動轉成字符串。

var array = [];
array[100] = 'a';

array.length; // 101
array[1]; // undefined

1 in array; // false

數組 array 只有一個成員,雖然 length 爲101,可是其餘位置的鍵名都會返回 false。

for...in 循環和數組的遍歷

for...in 循環不只能夠遍歷對象,也能夠遍歷數組。由於數組是對象。

var array = ['a', 'b', 'c'];
for (var i in array) {
    console.log(array[i]);
}
// 'a', 'b', 'c' 換行打印

for...in 不只會遍歷數組全部的數字鍵,也會遍歷非數字鍵。

var array = ['a', 'b', 'c'];
array.name = 'musibii';

for (var i in array) {
    console.log(array[i]);
}
// 'a', 'b', 'c', 'musibii'

在遍歷數組時,也會遍歷非整數鍵name,因此不建議使用for...in 遍歷數組。可使用 for 循環或者 while 循環。(這樣只會遍歷出整數的鍵名)

數組的空位

當數組的某個位置是空元素,即兩個逗號之間沒有任何值,那麼稱該數組存在空位。

var array = ['a', '', 'c'];
array.length; // 3
array[1]; // undefined

這表名數組的空位不影響 length 屬性的值。 而且空位是能夠被讀取的,只不過值爲 undefined。

使用 delete 命令能夠刪除數組中的某個成員,這樣會造成空位,和上面同樣不會影響數組的 length 屬性。

var array = ['a', 'b', 'c'];
delete array[1];
a[1]; //undefined
a.length; // 3

使用 delete 刪除了數組中的元素,不會影響數組的 length 屬性值,這樣若是使用 length 對一個數組進行遍歷時須要謹慎(這好奇怪啊。。。。)

數組的某個位置是空位,與某個位置是 undefined,是不同的。若是是空位,使用數組的 forEach 方法、for...in 結構以及 Object.keys 方法進行遍歷時,空位會被跳過。

不得不說,真的奇怪。這個設計思想也太靈活了8。。。

空位表示數組沒有這個元素,因此不會被遍歷到,而 undefined 表示數組有這個元素,值爲 undefined,這樣遍歷就不會跳過。

本文參考https://wangdoc.com/javascript/types/array.html