[JavaScript] MDN web docs 摘要 1: JavaScript 第一步

1 什麼是JavaScript

JavaScript 是一種腳本,一門編程語言,它可以在網頁上實現複雜的功能,網頁展現給你的不再是簡單的靜態信息,而是實時的內容更新,交互式的地圖,2D/3D 動畫,滾動播放的視頻等等。

1.1 瀏覽器 API

內建於 web 瀏覽器中,它們可以使周邊計算環境的數據暴露出來,還可以做實用的複雜工作。例如:

  • 文檔對象模型 API(DOM(Document Object Model)API) 能通過創建、移除和修改 HTML,爲頁面動態應用新樣式等手段來操作 HTML 和 CSS。比如當某個頁面出現了一個彈窗,或者顯示了一些新內容(像上文小 demo 中看到那樣),這就是 DOM 在運行。
  • 地理位置 API(Geolocation API) 獲取地理信息。這就是爲什麼 谷歌地圖 可以找到你的位置,而且標示在地圖上。
  • 畫布(Canvas) 和 WebGL API 可以創建生動的 2D 和 3D 圖像。人們正運用這些 web 技術製作令人驚歎的作品。參見 Chrome Experiments 以及 webglsamples。
  • 諸如 HTMLMediaElement 和 WebRTC 等 影音類 API 讓你可以利用多媒體做一些非常有趣的事,比如在網頁中直接播放音樂和影片,或用自己的網絡攝像頭獲取錄像,然後在其他人的電腦上展示(試用簡易版 截圖 demo 以理解這個概念)。

1.2 第三方 API

並沒有默認嵌入瀏覽器中,一般要從網上取得它們的代碼和信息。比如:

  • Twitter API 和 新浪微博 API 可以在網站上展示最新推文之類。
  • 谷歌地圖 API 和 高德地圖 API 可以在網站嵌入定製的地圖等等。

1.3 註釋

JavaScript 的註釋和C++ 一樣: //單行註釋/*多行註釋 */

1.4 解釋代碼 vs 編譯代碼

解釋(interpret)和 編譯(compile)。在解釋型語言中,代碼自上而下運行,且實時返回運行結果。代碼在執行前,無需由瀏覽器將其轉化爲其他形式。
與此同時,編譯型語言代碼能夠運行之前需要先轉化(編譯)成另一種形式。比如 C/C++ 先被編譯成彙編語言,然後才能由計算機運行。JavaScript 是輕量級解釋型語言。兩種方式各有優勢。

1.5 服務器端代碼 vs 客戶端代碼

客戶端(client-side)代碼是在用戶的電腦上運行的代碼,在瀏覽一個網頁時,它的客戶端代碼就會被下載,然後由瀏覽器來運行並展示。這就是客戶端 JavaScript。
而服務器端(server-side)代碼在服務器上運行,瀏覽器將結果下載並展示出來。流行的服務器端 web 語言包括:PHP、Python、Ruby、ASP.NET 以及 JavaScript。JavaScript 也可用作服務器端語言,比如現在流行的 Node.js 環境。

1.6 動態代碼 vs 靜態代碼

“動態”一詞既能描述客戶端 JavaScript,又能描述服務器端語言。是指通過按需生成新內容來更新 web 頁面 / 應用,使得不同環境下顯示不同內容。服務器端代碼會在服務器上動態生成新內容,例如從數據庫中提取信息。而客戶端 JavaScript 則在用戶端瀏覽器中動態生成新內容,比如說創建一個新的 HTML 表格,用從服務器請求到的數據填充,然後在網頁中向用戶展示這個表格。兩種情況的意義略有不同,但又有所關聯。
沒有動態更新內容的網頁叫做“靜態”頁面,所顯示的內容不會改變。

1.7 怎樣向頁面添加 JavaScript

使用<script>元素添加各種JavaScript:無論內部還是外部。

1.7.1 內部 JavaScript

code 直接加到html中,放在</head>標籤之前。

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <title>Apply JavaScript example</title>
    <script>
      // JavaScript goes here
      document.addEventListener("DOMContentLoaded", function() {
        function createParagraph() {
          let para = document.createElement('p');
          para.textContent = 'You clicked the button!';
          document.body.appendChild(para);
        }
        const buttons = document.querySelectorAll('button');
        for(let i = 0; i < buttons.length ; i++) {
          buttons[i].addEventListener('click', createParagraph);
        }
      });
    </script>
  </head>
  <body>
    <button>Click me</button>
  </body>
</html>

1.7.2 外部 JavaScript

外部JavaScript是指,將JavaScript腳本放到.js文件中,這是最佳的寫法,HTML和JS分開,易於維護,可重用。

function createParagraph() {
  let para = document.createElement('p');
  para.textContent = 'You clicked the button!';
  document.body.appendChild(para);
}

const buttons = document.querySelectorAll('button');

for(let i = 0; i < buttons.length ; i++) {
  buttons[i].addEventListener('click', createParagraph);
}

然後將<script> ...</script>替換成:<script src="script.js" defer></script>

1.7.3 內聯 JavaScript 處理器

有時候會看到下面這樣的代碼,即在button元素里加一個onclick處理器,但是這是不好的寫法,且每加一個button都要這樣寫,不好維護。

// !!!!!!!!!!!! bad practice! 不好的寫法,HTML和JS混合在一起
function createParagraph() {
  let para = document.createElement('p');
  para.textContent = 'You clicked the button!';
  document.body.appendChild(para);
}
<button onclick="createParagraph()">Click me!</button>

1.8 腳本加載策略

如果要用JS操作DOM,那麼DOM一定要先於javascript被加載。
老的解決方法是將JS腳本放在</body>標籤之前,這種方法使HTML DOM在加載之前,javascript的加載/解析完全被阻止,效率低。

1.8.1 asyncdefer

1.7.1 內部 javascript 的例子:

document.addEventListener("DOMContentLoaded", function() {
  ...
});

事件監聽器監聽 DOMContentLoaded事件,代表HTML body已經完全加載並解析。此事件被觸發之後,javascript 纔會運行。

asyncdefer 僅對外部 javascript 起作用,它們之間的區別示意圖
在這裏插入圖片描述

<script       src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
  • Without async or defer, browser will run your script immediately, before rendering the elements that’s below your script tag.
  • With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
  • With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
<script defer src="js/vendor/jquery.js"></script>
<script defer src="js/script2.js"></script>
<script defer src="js/script3.js"></script>

使用defer能保證腳本按順序加載,jquery.js, script2.js, script3.js ,使用 async 則不然。

如果多個腳本不需要等待解析(???),能獨立執行,用async, 反之用defer

2 初次接觸 JavaScript

JavaScript 的很多代碼特性和其他編程語言是一樣的,比如函數啊,循環之類的,代碼語法看起來不同,但概念基本是一樣的。

用關鍵字let(或 var創建變量),用 const創建常量(這點和C++一樣)。

定義函數有很多方式,其中一種是用關鍵字function定義,舉例如下:

function checkGuess() {
  alert('I am a placeholder');
}

如果在瀏覽器的JavaScript Console調用這個函數,會彈出對話框。
在這裏插入圖片描述操作符 + - * /可以進行算術運算,還可以進行字符串連接。
在這裏插入圖片描述還允許快捷操作符:

name += ' says hello!';

++操作符也可以用: guessCount++;
比較操作符,這裏比較相等和不等與其他語言不同,多一個等號。
但是 ==!=在JavaScript裏也是合法的操作符,但和嚴格相等符號===相比,==只看值是否相等,不管數據類型是否相同,因此應該使用===符號,可以減少錯誤發生的可能性。
在這裏插入圖片描述條件,if, else if, else和C++ 語法是一樣的。

對於JavaScript語言,一切都是對象,用戶可以自己創建對象。

3 出現了什麼問題?JavaScript 疑難解答

JavaScript 大小寫敏感。

console.log()是非常有用的調試函數,可以將值輸出到控制檯。
類選擇器以點號 .開始。

如果是Firefox, 用 Ctrl + Shift + K, 打開console,可以看到可能的錯誤提示。

4 儲存你所需的信息 — 變量

4.1 用letvar聲明變量

聲明變量時不需要指定類型:

let myName;
let myAge;

在JavaScript中,所有代碼指令以分號結束。
同時聲明並初始化變量:

let myDog = 'Rover';

varlet的區別:
var是老的,let是新的,可以在變量初始化之後,再次用var關鍵字聲明。例如:

myName = 'Chris';
function logName() {
  console.log(myName);
}
logName();
var myName;

此外,下面的代碼是合法的,如果var改成let就不合法:

var myName = 'Chris';
var myName = 'Bob';

要儘量使用let而非 var,除非是要支持舊版的IE,一些舊版的IE只支持var,不支持let

4.2 變量命名規則:

  • 1 變量名由(0-9, a-z, A-Z) 以及下劃線組成
  • 2 不要以下劃線開頭
  • 3 不要以數字開頭
  • 4 不能用保留字當變量名

4.3 變量類型:

  • 數字:有整型,也有浮點型, let myAge = 17;
  • 字符串 :可用單引號或雙引號, let dolphinGoodbye = 'So long and thanks for all the fish';
  • 布爾:值爲truefalse, let iAmAlive = true;
  • 數組:let myNameArray = ['Chris', 'Bob', 'Jim']; 第一個元素的index是0
  • 對象:let dog = { name : 'Spot', breed : 'Dalmatian' }; 然後 dog.nameSpot

動態類型:不需要指定變量的數據類型

let myNumber = '500'; // oops, this is still a string
typeof myNumber;  // return "string"
myNumber = 500; // much better — now this is a number
typeof myNumber;  // return "number"

4.4 常量

常量聲明之後,值不可再次改變,和其他語言一樣。
使用const關鍵字:

const daysInWeek = 7;
const hoursInDay = 24;
daysInWeek = 8; // 拋出錯誤:TypeError: invalid assignment to const `daysInWeek'

5 JavaScript 基礎概念 — 數字與運算符

5.1 JavaScript 只有一種數字的數據類型: Number.

let myInt = 5;
let myFloat = 6.667;
myInt;  // 5
myFloat;  // 6.667
typedef myInt;  // “number”
typedef myFloat; // "number"

5.2 操作符

操作符和其他語言類似, 有 + - * / % **, 最後一個是指數運算符:

10 ** 3 
= Math.pow(10, 3) 
= 10 * 10 * 10 
= 1000

除法運算和python類似,會給出浮點值:

10 / 9;
1.1111111111111112

表達式求和的順序總是從左到右。
++--操作符和C++的一樣。

let num1 = 4;
num1++;  //4
num1; //5
let num2 = 6;
num2--; //6
num2;  //5
let num3 = 6;
++num3; //7
num3;  //7

6 處理文字 — JavaScript 中的字符串

6.1 字符串

字符串可用單引號或雙引號,但是不能混用:

let badQuotes = 'What on earth?"; // ERROR!!!!!

6.2 轉義

轉義字符串中的字符,在字符前加反斜槓轉義字符:

let bigmouth = 'I\'ve got no right to take my place...';
bigmouth;  // "I've got no right to take my place..."

6.3 連接字符串:

+號,字符串字面值還可以和變量相加:

  let name = prompt('What is your name?');
  alert('Hello ' + name + ', nice to see you!');

數字可與字符串相加:

'Front ' + 242; // OK, "Front 242"

6.4 數字與字符串相互轉換

使用Number函數與toString() 方法:

let myString = '123';
let myNum = Number(myString);
typeof myNum;  // "number"
let myNum = 123;
let myString = myNum.toString();
typeof myString;  // "string"

7 字符串常用操作

字符串是對象。

7.1 字符串長度

使用 length屬性

let browserType = 'mozilla';
browserType.length;  // 7

7.2 檢索

同數組:

browserType[0]; // 使用索引,從0開始
browserType.indexOf('zilla'); // 如果未查找到,返回 -1,  判斷時,可使用 !== -1

indexOf()方法僅返回首次出現時的索引:The index of the first occurrence of searchValue, or -1 if not found.

7.3 字串

slice(a, b) 方法,a爲起始位置,b爲結束位置,實際取a ~ b-1。 如果 b省略,取a起始的全部字符,直到結束。

let browserType = "Mozilla";
browserType.slice(2); // 'zilla';

7.4 大小寫轉換

分別使用 toLowerCase()toUpperCase() 兩個方法。

7.4 字符串替換

let browserType = "Mozilla"; 
browserType.replace('moz','van');  // 僅對第一個匹配項進行替換

8 數組

8.1 創建數組

數組元素的數據類型可以不統一:

let random = ['tree', 795, [0, 1, 2]];

8.2 訪問和修改數組元素

同C++數組,沒有特別之處。

8.3 數組長度

使用 .length 屬性。

8.4 數組和字符串相互轉換

8.4.1 字符串轉換爲數組

let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
let myArray = myData.split(',');
myArray; //

8.4.2 數組轉換爲字符串

使用 join()toString() 方法, toString() 更簡單,但不能帶參數。

let dogNames = ['Rocket','Flash','Bella','Slugger'];
let myNewString = dogNames.join(';;');
myNewString; //"Rocket;;Flash;;Bella;;Slugger"
let myNewString2 = dogNames.toString();
myNewString2; // "Rocket,Flash,Bella,Slugger"

8.5 添加和刪除數組元素

從數組末尾添加刪除元素: push(), pop()
push() 可以帶多個參數,如果成功,返回新數組長度,pop() 不帶參數,如果成功,返回被刪除的元素。
從數組開頭添加刪除元素:unshift(), shift()
兩組方法沒有差別,只不過是一個對數組末尾的元素操作,一個對數組開頭的元素操作。

let myArray = ['Manchester', 'London', 'Birmingham', 'Leeds', 'Carlisle'];
let newLength = myArray.push('Bradford', 'Brighton');
myArray; // Array(7) [ "Manchester", "London", "Birmingham", "Leeds", "Carlisle", "Bradford", "Brighton" ]
newLength; // 7
let removedItem = myArray.pop();
myArray; // Array(6) [ "Manchester", "London", "Birmingham", "Leeds", "Carlisle", "Bradford" ]
removedItem; // "Brighton"

https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps/What_is_JavaScript

https://stackoverflow.com/questions/10808109/script-tag-async-defer/24183280#24183280

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