JavaScript語言基本例子
var usr = "danny", age = 18;
//ECMAScript 6, ES 6
const LED_PIN = 13; //宣告常數, 不能修改
//primitive type
//Boolean: true or false
//Number: 3.14
//String: "AAA"
//Null: null
//Undefined: undefined
//字串轉換成數自函式
Number("8.24") -> 8.24
Number("123abc") -> NaN
parseInt("8.24") -> 8
parseInt("123abc") -> 123
parseFloat("8.24") -> 8.24
var num = 0.1 * 0.2;
num.toPrecision(12) //精確度縮限制小數點12位
//嚴格相等運算子 ===
// 8 === "8"=> false
// 8 == "8" => true
x = ( x === undefined) ? 0 : x;
//在函式內以var宣告的變數, 都是區域變數, 以外定義的變數都是全域變數
//每隔5秒執行一次
window.setInterval(function() {
// do something
}, 5000);
//Array
var she = ["AAA", "BBB"];
var she = new Array("AAA","BBB");
var she = new Array(3); //三個元素空白陣列
var she = [];
she.push("CCC"); //後面添加新元素
she.pop(); //刪除最後一個元素並傳回
she.unshift("DDD"); //在陣列前最前面加入新元素
she.shift(); //刪除並傳回第一個元素
she.splice(1,1); //在index=1的位置刪除一個元素
she.splice(1,1, "EEE", "FFF"); //在index=1的位置刪除一個元素,並加入兩個新元素
//for迴圈
for(var i=0; i<total; i++) {
}
she.forEach( function(val) {
});
//Object
var obj = {name:"Danny", age:18};
delete obj.name; // delete指令僅能刪除物件的屬性
for( var key in obj){
var val = obj[key];
console.log("attr:" + key + ",value:" + val);
}
BOM ( Brower Object Model ) 與 DOM ( Document Object Model )
操作網頁物件
var n1 = document.getElementById("num1");
window.alert("");
window.confirm("");
location.href = "<http://swf.com.tw>"
事件處理程式
ES 6 (ECMAScript 6 or ECMAScript 2015)
let 區域化變數的存範圍
const常數宣告
Data Type 資料型別
for ... of 巡覽迴圈
for (variable of iterable) {
statement
}
其中 variable 直接是值,而不是索引。
let iterable = [10, 20, 30];
for (let valueof iterable) {
value += 1;
console.log(value);
}
Template字串模板
模版字符串中,我們還可以透過 ${...} 這樣的方式,嵌入變量或任何的表達式:
let myName = "PJCHENder", numA = 4, numB = 7;
let content = `Hello, my name is ${myName}, my lucky number is ${2*(numA + numB)}`;
// "Hello, my name is PJCHENder, my lucky number is 22"
console.log(content);
Arrow Function 箭頭函數
(參數1, 參數2, …, 參數N) => { 陳述式; }
// 等相同(參數1, 參數2, …, 參數N) => { return 表示式; }
// 只有一個參數時,括號才能不加: (單一參數) => { 陳述式; } 單一參數 => { 陳述式; }
//若無參數,就一定要加括號: () => { statements }
(參數1, 參數2, …, 參數N) => 表示式;
// 當函數會直接回傳值,可以省略箭頭後面的大括號
// 當函數會直接回傳物件,物件外需要使用小括號包起來
// 用大括號將內容括起來,返回一個物件字面值表示法: params => ({foo: bar})
// 支援其餘參數與預設參數 (param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
// 也支援 parameter list 的解構 var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
範例:
function area(p, r) {
return p * r * r;
}
//箭頭函數
(p, r) => p * r * r
let pi = 3.14159
let radius = 10
const area = (p, r) => p * r * r
let result = `
圓周率 pi 為 ${pi} 半徑為 ${radius}
圓周長是 ${ 2 * pi * radius }
圓面積是 ${ area(pi, radius)}
`
const Cicle = (p, r) => ({
pi:pi,
radius:r,
area:p*r*r
})
展開語法
const mphone = {
name: 'm phone',
myear: '2018',
};
const iphone = {
...mphone,
name: 'i phone',
iyear: '2019',
};
const mphone = ['phone1','phone1','phone1'];
const iphone = [...mphone, 'Oppp', 'Vivo'];
Rest Parameters 餘下參數
其餘參數(Rest parameters)的語法代表是"不確定的傳入參數值",例如最典型的就是下面這個加總的範例:
function sum(…numbers) {
var result = 0;
numbers.forEach(function (number) {
result += number;
});
return result;
}
console.log(sum(1));// 1
console.log(sum(1, 2, 3, 4, 5));// 15
numbers參數,會把傳給它的"其餘"的所有值,轉換成一個數值陣列。
它可以把在解構賦值中沒有被取出來的物件屬性或是陣列元素都放到一個壓縮包內,例如:
const mphone = {
name: 'm phone',
pyear: '2018',
feature: '3camera',
status: 'good'
};
const {name, pyear, ...other} = mphone;
// other物件內含
// { feature: '3camera',
// status: 'good'
// }
Object Literal物件參數
const Danny1 = {
name: name,
age: 18,
showInfo: function(){
return `${this.name} is ${this.age} years old!`
}
}
// or
const Danny1 = {
name,
age: 18,
showInfo(){
return `${this.name} is ${this.age} years old!`
}
}
Array物件常見的方法
// 相同的陣列
var people = [
{
name: 'Casper',
like: '鍋燒意麵',
age: 18
},
{
name: 'Wang',
like: '炒麵',
age: 24
},
{
name: 'Bobo',
like: '蘿蔔泥',
age: 1
},
{
name: '滷蛋',
like: '蘿蔔泥',
age: 3
}
];
every()
用來測試陣列中的所有元素是否"全部通過"所指定函數所給定的測試
const scores = [59,62,38,77,86]
const result = scores.every((score) => score >= 60)
some()
用來測試陣列中的所有元素中"任一個通過"所指定函數所給定的測試
const scores = [59,62,38,77,86]
const result = scores.find((score) => score >= 60)
forEach()
用來"逐一巡覽"陣列中所有的元素
const scores = [59,62,38,77,86]
scores.forEach((score) => {
if(score >= 60){
result.push(score)
}
})
map()
用來"逐一巡覽"陣列中所有的元素,然後經過指定函數所給定的處理
const scores = [59,62,38,77,86]
scores.map((score) => score + 10)
reduce()
用來"逐一巡覽"陣列中所有的元素,累加所有元素後,將濃縮後(reduce)的加總值傳回。
const scores = [59,62,38,77,86]
let sum = 0
scores.map((score) => {
sum += score
})
console.log(sum) //332
let ret = scores.reduce((sum, score) => {
//console.log(sum); // 59, 121, 159, 236
//console.log(score); // 62, 38, 77, 86
return sum + score
})
console.log(ret) //332
slice()
依指定的 "起" "迄" 位置,切一塊新陣列物件出來,原本的陣列將不會被修改
let books = ['book 1','book 2','book 3','book 4','book 5']
console.log(books.slice(2)) //['book 2','book 3','book 4','book 5']
console.log(books.slice(2,4)) //['book 3','book 4']
splice()
依第一參數指定的"索引位置"來"增刪"現有陣列的元素。第二參數表示要刪除的元素"數量",第三參數以後表示要新增的元素。
let books = ['book 1','book 2','book 3','book 4','book 5']
//從索引位置2, 不刪, 加1個元素
console.log(books.splice(2,0,"book added"))
//從索引位置4, 刪2個元素, 加2個元素
console.log(books.slice(4,2,"new 1", "new 2"))
//從索引位置4, 刪所有元素
console.log(books.slice(4))
Function Chaining
const scores = [59,62,38,77,86]
let sum = 0
let result = scores
.filter((score) => score >= 60)
.reduce((sum, score) => sum + score)
console.log(result)
Async/await
async function
是不管怎樣都會回傳 Promise
的函式。例如:
const foo = async () => {
return 1;
}
foo().then((res) => {
console.log(res);
});
雖然我們的 foo
回傳的不是一個 Promise
,但因為它是 async function
的關係,JS 會自動把它包成 Promise
,所以可以使用 then
,結果會得到 1。
而 await
則是可以等 Promise
執行完再執行下一行:
const demo = async () => {
await logAsync('1 秒後會出現這句', 1000);
await logAsync('再 1.5 秒後會出現這句', 1500);
await logAsync('再 2 秒後會出現這句', 2000);
};
demo();
不過 await
必須在 async function
裡面才能使用。
而且 await
也能夠把 Promise
回傳的值接起來,通常我們在呼叫 API(例如執行 fetch
、axios
)的時候就很好用:
(async () => {
const res = await fetch('API_URL');
const data = await res.text();
console.log(data);
})();
搭配 axios
更可以這樣使用:
((async () => {
const { data } = await axios.get('API_URL');
console.log(data);
})();
Promise
簡單的 Promise 範例:
// 宣告 promise 建構式
let newPromise = new Promise((resolve, reject) => {
// 傳入 resolve 與 reject,表示資料成功與失敗
let ran = parseInt(Math.random() * 2); // 隨機成功或失敗
console.log('Promise 開始')
if (ran) {
setTimeout(function(){
// 3 秒時間後,透過 resolve 來表示完成
resolve('3 秒時間(fulfilled)');
}, 3000);
} else {
// 回傳失敗
reject('失敗中的失敗(rejected)')
}
});
newPromise.then((data)=> {
// 成功訊息 (需要 3 秒)
console.log(data);
}).catch((err)=> {
// 失敗訊息 (立即)
console.log(err)
});
執行 Promise 建構式時還會再帶入 resolve 與 reject 的 callback function。
- resolve: 完成的 callback
- reject: 失敗的 callback
Promise 的生命週期
- pending: 等待中的初始狀態
- fulfilled: 正確完成
- rejected: 已拒絕,操作失敗
Module模組
// test.js
const scores = [59,62,38,77,86]
let sum = 0
let sum_func = scores.map((score) => {
sum += score
})
let ret = scores.reduce((sum, score) => {
//console.log(sum); // 59, 121, 159, 236
//console.log(score); // 62, 38, 77, 86
return sum + score
})
export {
scores,
sum,
sum_func,
ret as ReturnData
}
======================================
import * as Danny from "./test.js"
console.log(Danny.sum)
匯入 default export 並賦予名稱
預設匯出每個檔案僅會有一個,並且不會給予名稱,這種匯入方式會將預設匯出的模組引入,並且重新賦予一個變數名稱。
// export file
export default function() {
console.log('這是一段函式');
}
// import file
import fn from './defaultModule.js';
fn(); // 直接執行函式
匯入 named export
具名的匯出方式,則需要使用解構的語法將特定的模組取出(命名需與匯出的名稱一致),並且只有被匯入的原始碼片段才能夠被執行。
// export file
export const obj = { name: 'obj'}; // 此段如果沒有被匯入,則無法運作
export function fn() {
console.log('這是一段函式')
}
// import file
import { fn } from './module.js';
fn();
也可以透過解構同時匯入多個物件、變數、函式等等。
// import file
import { fn, obj } from './module.js';
fn();
console.log(obj)
重新命名
具名匯出的物件、變數本身就帶有固定的名稱,如果要避免與當前的作用域產生衝突,則可以使用 as
(alias) 來重新命名匯入的名稱。
// export file
export const obj = { name: 'obj'};
export function fn() {
console.log('這是一段函式')
}
// import file
import { fn as newFn } from './module.js';
newFn();
同時匯入預設、具名
匯出時可同時存在兩種形式,因此匯入時也同樣支援。以下片段來說,在匯入時前者是帶入 default export
,逗點後方則是帶入 named export
:
import defaultExport, * as name from "module-name";
No comments:
Post a Comment