20200224 JavaScript【1】快速入門

2020.02.24-26爲js入門學習期
參考 ①(主)廖雪峯教程 ②(輔)菜鳥教程


一 JS簡介

JavaScript是世界上最流行的腳本語言,因爲你在電腦、手機、平板上瀏覽的所有的網頁,以及無數基於HTML5的手機App,交互邏輯都是由JavaScript驅動的。簡單地說,JavaScript是一種運行在瀏覽器中的解釋型的編程語言。在Web世界裏,只有JavaScript能跨平臺、跨瀏覽器驅動網頁,與用戶交互。隨着HTML5在PC和移動端越來越流行,JavaScript變得更加重要了。並且,新興的Node.js把JavaScript引入到了服務器端,JavaScript已經變成了全能型選手

廖佬的提醒:由於瀏覽器在發佈時就確定了JavaScript的版本,加上很多用戶還在使用IE6這種古老的瀏覽器,這就導致你在寫JavaScript的時候,要照顧一下老用戶,不能一上來就用最新的ES6標準寫,否則,老用戶的瀏覽器是無法運行新版本的JavaScript代碼的。(不過,JavaScript的核心語法並沒有多大變化。我們的教程會先講JavaScript最核心的用法,然後,針對ES6講解新增特性。)

二 光速入門

1、JS & HTML

JavaScript代碼可以直接嵌在網頁的任何地方,不過通常我們都把JavaScript代碼放到head中

<html>
<head>
  <script>
    alert('Hello, world');
  </script>
</head>
<body>
  ...
</body>
</html>

script中包含的代碼就是JavaScript代碼,它將直接被瀏覽器執行。
以上是方法一

方法二: 使用.js文件
js的代碼寫在.js文件中,然後在HTML的head中通過一句話引入這個文件——

<html>
<head>
  <script src="/static/js/abc.js"></script>
</head>
<body>
  ...
</body>
</html>

這種做法更利於維護代碼,並且多個頁面可以各自引用同一份.js文件。

2、文本編輯器

★可以用任何文本編輯器來編寫JavaScript代碼,廖雪峯依舊推薦VScode!
注意:儘量不要用記事本編寫JavaScript或HTML,它會自作聰明地在保存UTF-8格式文本時添加BOM頭。

3、JS的註釋

跟cpp一樣!

// 以雙斜槓開頭直到行末的是註釋,註釋是給人看的,會被瀏覽器忽略
/* 從這裏開始是塊註釋
仍然是註釋
仍然是註釋
註釋結束 */

4、調試

①點擊f12
②chrome的開發者工具打開

然後,點擊“控制檯(Console)“,在這個面板裏可以直接輸入JavaScript代碼,按回車後執行。比如:要查看一個變量的內容,在Console中輸入console.log(a); ,回車後顯示的值就是變量的內容。在編寫JavaScript代碼時,經常需要在Console運行測試代碼。

三 基礎內容

1、語法

JavaScript的語法和Java語言類似,每個語句以;結束,語句塊用{…}。

賦值語句:

var x = 1;

語句塊是一組語句的集合,例如,下面的代碼先做了一個判斷,如果判斷成立,將執行{…}中的所有語句:

if (2 > 1) {
    x = 1;
    y = 2;
    z = 3;
}

語句具有縮進,通常是4個空格。但縮進不是JavaScript語法要求必須的!
{…}還可以嵌套,形成層級結構: //跟C幾乎一樣…

if (2 > 1) {
    x = 1;
    y = 2;
    z = 3;
    if (x < y) {
        z = 4;
    }
    if (x > y) {
        z = 5;
    }
}

注意:過多的嵌套無疑會大大增加看懂代碼的難度。遇到這種情況,需要把部分代碼抽出來,作爲函數來調用,這樣可以減少代碼的複雜度

提醒:
JavaScript嚴格區分大小寫,如果弄錯了大小寫,程序將報錯或者運行不正常!

2、數據類型

計算機能處理的數據遠不止數值,它還可以處理文本、圖形、音頻、視頻、網頁等各種各樣的數據,不同的數據,需要定義不同的數據類型。在JavaScript中定義了以下幾種數據類型:

  1. Number
    JavaScript不區分整數和浮點數,統一用Number表示。
    特別記下:
    ①NaN——無法計算結果(Not a Number)
    ②Infinity——無窮大(當數值超過了JavaScript的Number所能表示的最大值時)
1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1  (%是求餘運算)
10.5 % 3; // 1.5
  1. 字符串
    字符串是以單引號’或雙引號"括起來的任意文本(類似python)。
    如果’本身也是一個字符,那就可以用"“括起來,比如"I’m OK” 。

★如果字符串內部既包含’又包含"怎麼辦?可以用轉義字符“\”來標識,比如:
(好像就是和python一樣一樣的…)

'I\'m \"OK\"!';  //輸出:I'm "OK"!

★轉義字符:

\n表示換行,\t表示製表符,字符\本身也要轉義,所以\表示的字符就是\ 。

★多行字符串的寫法舉例:【“ ` ”是英文輸入時,esc下面的那個按鍵!】

console.log(`多行
字符串
測試`); //輸出分爲三行顯示!

★模板字符串
要把多個字符串連接起來,可以用+號連接

var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '歲了!';
alert(message);

output:你好, 小明, 你今年20歲了!

★字符串的常見操作
①求長度

var s = 'Hello, world!';
s.length; // 13

②要獲取字符串某個指定位置的字符,使用類似Array的下標操作:
(索引從0開始)

var s = 'Hello, world!';

s[0]; // 'H'
s[6]; // ' '
s[7]; // 'w'
s[12]; // '!'
s[13]; // undefined 超出範圍的索引不會報錯,但一律返回undefined

字符串是不可變的,如果對字符串的某個索引賦值,不會有任何錯誤,但是,也沒有任何效果!例如:

var s = 'Test';
s[0] = 'X';
alert(s); // s仍然爲'Test'

注意:js爲字符串提供了一些常用方法(下面介紹的都是),調用這些方法本身不會改變原有字符串的內容,而是返回一個新字符串~

④toUpperCase( ) 【全都變大寫】

var s = 'Hello';
s.toUpperCase(); // 返回'HELLO'

⑤toLowerCase( )【全都變小寫】

var s = 'Hello';
var lower = s.toLowerCase(); // 返回'hello'並賦值給變量lower
lower; // 'hello'

⑥indexOf( ) 【搜索指定字符串出現的位置】

var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 沒有找到指定的子串,返回-1

⑦substring( ) 【返回指定索引區間的子串】

var s = 'hello, world'
s.substring(0, 5); // 從索引0開始到5(不包括5),返回'hello'
s.substring(7); // 從索引7開始到結束,返回'world'
  1. 布爾值
    布爾值和布爾代數的表示完全一致,一個布爾值只有true、false兩種值
    相關補充:

&& 運算是與運算
|| 運算是或運算
! 運算是非運算

布爾值經常用在條件判斷中(if語句)。
另外,比較運算符同cpp。

★ 實際上,JavaScript允許對任意數據類型做比較:

false == 0; // true
false === 0; // false

js有兩種比較運算符——

①第一種是==比較
它會自動轉換數據類型再比較,很多時候,會得到非常詭異的結果(上面的代碼)

②第二種是===比較 【始終堅持使用這個方式
它不會自動轉換數據類型,如果數據類型不一致,返回false,如果一致,再比較。

上面這坨概括起來就是:js中的等號是三個等號。

  1. null和undefined
    null表示一個“空”的值,它和0以及空字符串’ '不同。
    而undefined表示值未定義。
    大多數情況下,我們都應該用null。undefined僅僅在判斷函數參數是否傳遞的情況下有用。

  2. 數組
    數組是一組按順序排列的集合,集合的每個值稱爲元素。JavaScript的數組可以包括任意數據類型。例如:[1, 2, 3.14, ‘Hello’, null, true];
    數組的元素可以通過索引來訪問。請注意,索引的起始值爲0

var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引爲0的元素,即1
arr[5]; // 返回索引爲5的元素,即true
arr[6]; // 索引超出了範圍,返回undefined

Array可以通過索引把對應的元素修改爲新的值,因此,對Array的索引進行賦值會直接修改這個Array:(如果通過索引賦值時,索引超過了範圍,會引起Array大小的變化,越界訪問索引不會報錯! )

var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr[5] = 'x';
arr; // arr現在變爲['A', 99, 'C',undefined, 'x']

★ indexOf( )返回索引值
看例子就懂了——

var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引爲0
arr.indexOf(20); // 元素20的索引爲1
arr.indexOf(30); // 元素30沒有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引爲2

★ slice( )截取部分元素並返回一個新的array
看例子就懂了——

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 從索引0開始,到索引3結束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 從索引3開始到結束: ['D', 'E', 'F', 'G']

(0,3)潛在含義:左閉右開區間 !

★ push和pop 【尾部操作】
push()向Array的末尾添加若干元素,pop()則把Array的最後一個元素刪除掉!
看例子就懂——

var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的長度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 連續pop 3次
arr; // []
arr.pop(); // 空數組繼續pop不會報錯,而是返回undefined
arr; // []

★ unshift和shift 【頭部操作】
如果要往Array的頭部添加若干元素,使用unshift()方法,shift()方法則把Array的第一個元素刪掉!
看例子吧——

var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的長度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 連續shift 3次
arr; // []
arr.shift(); // 空數組繼續shift不會報錯,而是返回undefined
arr; // []

★ sort( ) 排序
(直接調用時,按照默認順序排序)

var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']

★ reverse 數組反向

var arr = ['one', 'two', 'three'];
arr.reverse(); 
arr; // ['three', 'two', 'one']

★★ 萬能的 splice( ) —— 修改操作會這個就夠!

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 從索引2開始刪除3個元素,然後再添加兩個元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回刪除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只刪除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不刪除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因爲沒有刪除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

★ concat( ) 連接兩個數組

var arr = ['A', 'B', 'C'];
var haha = arr.concat([1, 2],3); //concat還可以接收到數組
haha; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']

★ join( )
P.S. 聽說很實用,但小白實在看不懂實用在哪…廖佬說是就是吧…
join( )把當前Array的每個元素都用指定的字符串連接起來,然後返回連接後的字符串——

var arr = ['A', 'B', 'C', 1, 2, 3]; //如果Array的元素不是字符串,將自動轉換爲字符串後再連接。
arr.join('-'); // 'A-B-C-1-2-3'

★多維數組
如果數組的某個元素又是一個Array,則可以形成多維數組,例如:
var arr = [[1, 2, 3], [400, 500, 600], ‘-’];
上述Array包含3個元素,其中頭兩個元素本身也是Array。

  1. 對象 (類似C的結構體!)
    JavaScript的對象是一組由 鍵-值 組成的無序集合,例如:
var person = {
    name: 'Bob', //注意:是逗號!!!
    age: 20,
    tags: ['js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
    zipcode: null  //警告:最後一個屬性不必加逗號了不然可能報錯!!
};

JavaScript對象的鍵都是字符串類型,值可以是任意數據類型。上述person對象一共定義了6個鍵值對,其中每個鍵又稱爲對象的屬性,例如,person的name屬性爲’Bob’,zipcode屬性爲null。

要獲取一個對象的屬性,我們用 對象變量.屬性名 的方式:

person.name; // 'Bob'
person.zipcode; // null

【騷】由於JavaScript的對象是動態類型,你可以自由地給一個對象添加或刪除屬性: (看完就懂系列——)

var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一個age屬性
xiaoming.age; // 18
delete xiaoming.age; // 刪除age屬性
xiaoming.age; // undefined

3、變量

變量名的起名方式同其他語言。
申明一個變量用var語句,比如:

var a; // 申明瞭變量a,此時a的值爲undefined
var $b = 1; // 申明瞭變量$b,同時給$b賦值,此時$b的值爲1
var s_007 = '007'; // s_007是一個字符串
var Answer = true; // Answer是一個布爾值true
var t = null; // t的值是null

可以把任意數據類型賦值給變量,同一個變量可以反覆賦值,而且可以是不同類型的變量但是要注意只能用var申明一次,例如:

var a = 123; // a的值是整數123
a = 'ABC'; // a變爲字符串

這種變量本身類型不固定的語言稱之爲動態語言

補充:
靜態語言在定義變量時必須指定變量類型,如果賦值的時候類型不匹配,就會報錯。例如Java是靜態語言。

輸出:要顯示變量的內容,可以用console.log(x),打開Chrome的控制檯就可以看到結果。使用console.log()代替alert()的好處是可以避免彈出煩人的對話框

4、strict模式 (嚴格模式)

在JavaScript代碼的第一行寫上該代碼即可開啓strict模式:

'use strict';

寫這句話的用處——
在沒用var定義變量時,系統會報錯。

定義變量時一定要var來申明,否則會造成全局變量的產生!如:

i = 10; // i現在是全局變量

在同一個頁面的不同的JavaScript文件中,如果都不用var申明,恰好都使用了變量i,將造成變量i互相影響,產生難以調試的錯誤結果。而使用var申明的變量則不是全局變量,它的範圍被限制在該變量被申明的函數體內,同名變量在不同的函數體內互不衝突。

5、條件判斷 (if…else…)

操作和c語言一模一樣!另外,建議永遠都要寫上{ }。

也可以 if…else if …else{ }

6、循環(主要是2種)

No.1 for循環

var x = 0;
var i;
for (i=1; i<=10000; i++) //和c一樣的!
{
    x += i;  //也是可以這樣寫的!
}
x; // 50005000

for循環的3個條件都是可以省略的,如果沒有退出循環的判斷條件,就必須使用break語句退出循環。

★另一重要例子——

'use strict';
var arr = ['Bart', 'Lisa', 'Adam'];
var i;

for(i=0;i<arr.length;i++){
    console.log(`hello, ${arr[i]}!`) //注意看這句話怎麼寫的!!!!!
};

output
hello, Bart!
hello, Lisa!
hello, Adam!

No.2 for…in循環
for循環的一個變體。它可以把一個對象的所有屬性依次循環出來:
(和python一樣)看完就懂了——

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {    /*注意for裏面的寫法*/
    console.log(key); // 'name', 'age', 'city'
}

No.3 while循環
跟c語言一模一樣~~看例子吧:

var x = 0;
var n = 99;
while (n > 0) {
    x = x + n;
    n = n - 2;
}
x; // 2500

No.4 do…while循環

var n = 0;
do {
    n = n + 1;
} while (n < 100);
n; // 100

注意:用do { … } while( )循環要小心,循環體會至少執行1次,而for和while循環則可能一次都不執行!

7、Map

Map是一組鍵值對的結構,具有極快的查找速度。

給定一個名字,要查找對應的成績:只需要一個“名字”-“成績”的對照表,直接根據名字查找成績,無論這個表有多大,查找速度都不會變慢。用JavaScript寫一個Map如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

初始化Map需要一個二維數組,或者直接初始化一個空Map。Map具有以下方法:

var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.set('Bob', 62);// 會刷新掉上一行記錄的59~
m.get('Bob'); // 62
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 刪除key 'Adam'
m.get('Adam'); // undefined

8、Set 集合

Set和Map類似,也是一組key的集合,但不存儲value
在Set中,沒有重複的key!

要創建一個Set,需要提供一個Array作爲輸入,或者直接創建一個空Set:

var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3

提醒:重複元素在Set中自動被過濾!!
look——
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}

通過add(key)方法可以添加元素到Set中,可以重複添加,但不會有效果:

s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}

通過delete(key)方法可以刪除元素。

9、iterable (可迭代的)

遍歷Array可以採用下標循環,遍歷Map和Set就無法使用下標。爲了統一集合類型,ES6標準引入了新的iterable類型,Array、Map和Set都屬於iterable類型。具有iterable類型的集合可以通過新的for … of循環來遍歷

用for … of循環遍歷集合,用法如下:

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍歷Array
    console.log(x);
}
for (var x of s) { // 遍歷Set
    console.log(x);
}
for (var x of m) { // 遍歷Map
    console.log(x[0] + '=' + x[1]);
}

★for … of循環和for … in循環有何區別?

for … in循環由於歷史遺留問題,它遍歷的實際上是對象的屬性名稱。一個Array數組實際上也是一個對象,它的每個元素的索引被視爲一個屬性。當我們手動給Array對象添加了額外的屬性後,for … in循環將帶來意想不到的意外效果:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // '0', '1', '2', 'name'
}

for … in循環將把name包括在內,但Array的length屬性卻不包括在內。for … of循環則完全修復了這些問題,它只循環集合本身的元素:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
    console.log(x); // 'A', 'B', 'C'
}

對比以上兩個代碼段!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章