Chapter
Javascript介紹
- 什麼是Javascript
- 為何需要學Javascript
- 前端技能
Javascript核心
- 環境建置
- 基礎語法
- DOM
- Event Handler
- 非同步處理(Ajax)
ECMAScript 6
- 什麼是ECMAScript
- 預設值
- 宣告let、const
- 字串方式
- 箭頭函式
- callback hell
Common Functions
Framework
- 前端
- 後端
- APP
Practice
Reference & Recommend
- 線上閱讀
- 線上練習
- 線上社群
Javascript介紹
> 什麼是Javascript
在還沒接觸JavaScript的時候一直以為他與Java應該有什麼關聯,殊不知這是一個天大的誤解,Java和 JavaScript雖然名稱相似,但卻是熱狗和狗的差別。JavaScript是一種直譯式、基於原型(prototype based)的物件導向程式語言,但又具有函數式程式設計(Functional programming)的特性。在過去的一段時間他都一直被認為是玩具語言,難登大雅之堂。但隨著版本的更新,加上搭配NodeJS,讓JavaScript成為排行榜上的紅人,除了網頁開發外,在許多的領域都可以看到JavaScript的身影。
> 為何需要學Javascript
早期 :
中期:
晚期:
前端的世界千變萬化,各種框架的演變,每18個月難度就會提高一倍,但唯一不變的就是底層皆為JS!!這是就為什麼需要學Javascript。
> 前端技能
前端工程師該具備什麼基本技能:
Javascript核心
> 環境建置
環境 :
JavaScript的檔案可使用一般的文字編輯器,編輯後存成.js檔案,也可以使用VScode等編輯器進行開發,CodePen這個線上工具進行測試(也可以直接使用Chrome、Firefox、IE等瀏覽器的開發者工具)。除了編輯器外,實際開發上我們也會需要用到Node.js開發環境,用於伺服器端和網路應用的執行環境,和NPM套件管理系統。
引用方式 :
- 放在 <head></head>
<head>
<script>
alert(Hello JS);
</script>
</head>
- 放在 <body></body>
<body>
<script>
alert(Hello JS);
</script>
</body>
- 外部引用檔案置於 <head> 或 <body> 內
<script src="js/main.js"></script>
> 基礎語法
語法概念 :
- Typeof & Expression
- Var
- Array
- Object
- Function
- Constructor
- Regular Expression
1. Typeof & Expression :
基本資料型態有number、string與布林值boolean,而undefined為特殊的值,並有弱型態特性。
- number
NaN為number的特殊數值,NaN不等於任何值,NaN也不等於NaN,如果你要測試某值結果是否為NaN,則要用isNaN()函式。
var number = 10; // 宣告數值
parseInt("10", 10); // 將字串轉為十進位整數
NaN == NaN; // false
isNaN(NaN); // true
isNaN(1); // false
isNaN('a'); // true
- string
字串是基本資料型態,可使用單引號或雙引號來包括一串文字,用以表示字串。
var text = 'Hello JS'; // 宣告字串
text.length; // 8
- boolean
布林值只有兩個值,true與false。
Boolean(false) // false
Boolean(0) // false
Boolean('') // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
// False Family
Boolean(1) // true
Boolean(true) // true
- undefined
undefined是JavaScript中特殊的值,當你變數在初始的時候未給予任何值或試圖取得某個沒定義的變數(也沒指定null)時產生。
var abc;
typeof abc; // undefined
- 弱型態
弱型別語言,會在必要的時候,自動型態轉換為對應的包裹物件,取得了語法簡潔的優點,但必須多注意非預期型態轉換的問題。
'1' + 2 // '12' 若是字串與數字則是會優先轉為字串
'2' - '1' // 1
'2' - 1 // 1 若字串無法運算再轉為數字
'1' * '2' // 2
'2' / '1' // 2
1 + true // 2
1 + false // 1
- typeof
typeof 1; // 'number'
typeof NaN; // 'number'
typeof 'JS'; // 'string'
typeof false; // 'boolean'
typeof true; // 'boolean'
typeof []; // 'object'
typeof {}; // 'object'
typeof null; // 'object'
typeof undefined; // 'undefined'
- expression
在JavaScript中有兩個相等性運算子==
與===
,都可以判斷值或物件參考是否相同,簡單來說,前者會嘗試將==兩邊轉換為同一型態,再比較是否相等,但後者只要===
兩邊型態不一,就會判斷為false
1 == '1' // true
1 === '1' // false1 != '1' // false
1 !== '1' // true
2. Var :
JavaScript則為動態語言,其變數本身使用者無需宣告型態。
var JS = 1;
JS = 'Hello';
如果沒有宣告var或是在全域使用var宣告皆會被判定為全域變數(window),也可以在全域範圍中使用this來取得。
js = 1;
js; // 1
this.js; // 1
x在函式中使用var宣告為區域變數,但y並非使用var宣告,所以y是全域變數。
function func() {
var x = 1;
y = 2;
console.log(x);
}
fun(); // 1
x; // error
y; // 2
this.y; // 2
如果全域與區域中有同名的變數,則區域會暫時覆蓋全域。
var x = 1;
function func() {
var x = 2;
console.log(x);
}fun(); // 2
x // 1
3. Array :
var array = [
1,
"JS",
false,
{'a':1},
function(){
console.log(123)
}
];
4. Object :
{ key: value }--------------------------------------------------------------------var person = {
name: 'Giant',
speak: function() {
alert('Hello');
}
}person.name; // Giant
person['name']; // Giant
預設值
//此為建構函數方法var name;
var age;
function Person(name, age){
this.name = name || 'JS';
this.age = age || 2018;
}var p = new Person(); // 'JS' 2018
5. Function :
- 函式宣告方法
//一般函數的兩種寫法function Person(name){
return name
}orvar Person = function(name){
return name
}Person('Giant')
- 什麼是this?
此函式中使用了this,在呼叫函式時,每個函式都會有個this,然而this參考至哪個呼叫他的物件,以此為例SuperCar()中的this會參考至car1的物件。
var car1 = {
name: 'BMW',
price: '250W'
};function SuperCar(){
return '[' + this.name + ',' + this.price + ']';
}SuperCar.call(car1); //[BMW, 250W]
- 閉包(Closure)
以此函式為例sum建立了閉包,因為它將變數x關入(close)自己的範圍,而閉包關閉的是變數,而不是變數所參考的值。
function sum() {
var x = 1; function sum(y) {
return x+y;
}
return sum
}var func = sum();func(20); // 21
- Scope
使用var宣告,它的用途和函數活動範圍有關。在函數內以var宣告的變數,僅限函數活動範圍內可用,外部看不到,var是看函數,而不是區塊。JavaScript在查找變數時,會循著範圍鏈(Scope chain)一層一層往外找
var x = 10;function func() {
console.log(x);
}func();// 10
-------------------------------------------------------------------- var x = 10;function func() {
console.log(x);
var x = 20;
console.log(x)
}func();// undefined
// 20
6. Constructor :
使用時機為這些物件在建立時,具有相同的特性名稱,只不過特性值不同,像這樣的函式,接在new之後使用時,俗稱為建構式(Constructor)。
function SuperCar(name, price) {
this.name = name;
this.price = price;
}var car1 = new SupreCar('BMW', '250W');
var car2 = new SupreCar('BENZ', '300W');
//會建立為以下物件var car1 = {
name: 'BMW',
price: '250W'
};
var car2 = {
name: 'BENZ',
price: '300W'
}
- prototype
使用時機,物件上不具該特性時才會使用原型,如果你對物件設定某個特性,是直接在物件上設定了特性,而不是對原型設定了特性。
function SuperCar(name, price) {
this.name = name;
this.price = price;
}SuperCar.prototype.toString = function() {
return '[' + this.name + ', ' + this.price + ']';
};var car1 = new SuperCar('BMW', '250W'); car1; // {name: "BMW", price: "250W"}
car1.toString; // [BMW, 250W]
對c所參考的物件設定了price特性,但並不影響Car.prototype.price的值。
function Car() { }Car.prototype.price = 200; // 200var c = new Car();
c.price; // 200c.price = 300;
c.price; // 300Car.prototype.price; // 200
7. Regular Expression :
> DOM
- 什麼是DOM?
在DOM的標準下,定義了一份文件中所有的標籤,包括文字,都是一個物件,這些物件以文件定義的結構,形成了一個樹狀結構。
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Hello!JS!</h1>
<a href="index.html">Learning</a>
</body>
</html>
變成以下樹狀結構
document (Document)
|-html (HTMLHtmlElement)
|-head (HTMLHeadElement)
| |-title (HTMLTitleElement)
| |-Home (Text)
|
|body (HTMLBodyElement)
|-h1 (HTMLHeadingElement
| |-Hello!JS! (Text)
|
|-a (HTMLAnchorElement)
|-Learning (Text)
- DOM元素操作
根據ID名稱選取document.getElementById(elementId)
根據ID loadeddocument.getElementById(elementId).value = 'value'
example
根據ID加上元件document.getElementById(elementId).appendChild(elementItem);
example
根據ID取得值document.getElementById(elementId).value
根據ID顯示document.getElementById(elementId).innerHTML = x.value;
example
根據元素名稱選取document.getElementsByTagName(tagName)
根據名稱選取document.getElementsByName(name)
根據Class名稱選取document.getElementsByClassName(classname)
> Event Handler
- onclick
<button id="btn" class="btn"/>function func() {
alert('Hello');
}document.getElementById('btn').onclick = func;--------------------------------------------------------------------<button id="btn" class="btn" onclick="func()"/>function func() {
alert('Hello');
}
- keyup
<input type="text" id="fname" onkeyup="myFunction()">function myFunction() {
var x = document.getElementById("fname");
x.value = x.value.toUpperCase();
}
> 非同步處理(Ajax)
非同步係指程式不會因為上一個函數尚未執行完就卡住,會往下執行下一個任務。
if (typeof XMLHttpRequest != 'undefined') {
// 一般使用 XMLHttpRequest 物件
const xhr = new XMLHttpRequest();
const REQUEST_URL = 'http://127.0.0.1/download/test.json'; // 監聽是否完成
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(xhr.responseText);
}
}
xhr.open('GET', REQUEST_URL);
xhr.send();
}
ECMAScript 6 (ES6)
> 什麼是ECMAScript
JavaScript 的創造者Netscape公司,將JavaScript提交給標準化組織ECMA,希望這種語言能夠成為國際標準。ECMAScript為JavaScript的規格,因此在日常場合,這兩個詞是可以互換的。
> 預設值
function SuperCar(name = 'BENZ', price = 200){
this.name = name;
this.price = price;
}
> 宣告let、const
- var,一般變數的宣告但要注意的是block != scope。
- let,此變數的用法符合真正的區域變數block = scope。
- const,凡是用const定義的符號,其繫結的內容僅能在定義時設定初值,之後不允許再改變。這就是常數了。試圖改變 const 常數的敘述,都是語法錯誤。除此之外,const的語法限制和let相同,不允許重複宣告、不允許宣告前使用。
> 字串方式
let object = {
name: 'BENZ',
price: 200
};
let car = `${object.name},${object.price}`;
car; // "BENZ,200"
> 箭頭函式
- Function
let Car = (name) => {
console.log(name)
}
- class
class Car {
constructor(name, price) {
this.name = name;
this.price = price;
}
buy() {
return `Name:${this.name}, Age:${this.price}`;
}
}let car = new Car('BENZ', 200);
Car.buy(); // {name: "BENZ", price: 200}
> callback hell
Common Functions
alert("輸入錯誤");
顯示一個警告對話框,包括一個OK按鈕。confirm("確定否!");
顯示一個確認對話框,包括OK、Cancel按鈕。math.length;
返回此變數的長度。Math.floor(1.6);
回傳1,返回一個數字的最大整數值。Math.max(5, 10);
回傳10,返回兩個數的最大值。Math.min(5, 10);
回傳5,返回兩個數的最小值。Math.random();
返回一個0~1的隨機數值。string.substr(start, end);
擷取字串中start到end的那一段字。array.sort();
將數組元素重新排序。array.include("value");
回傳true or false,找值是否存在此陣列。array.findIndex(index => index);
回傳此值在此陣列的位置。array.forEach(i => console.log(i));
迴圈array.map(i => i);
印出陣列array.every(i => i === x);
判斷陣列全部符合條件就印true,只要有一個不符合就會印false。array.splice(index, 0);
方法可以藉由刪除既有元素並/或加入新元素來改變一個陣列的內容。array.filter();
方法會建立一個經指定之函式運算後,由原陣列中通過該函式檢驗之元素所構成的新陣列。