功能介紹 登錄 首頁 修改密碼 提交申請 提交列表 數據可視化 審核列表 前端 components結構 搭建Vue項目 Vue3快速上手: https://cn.vuejs.org/guide/quick-start.html#creating-a-vue-application 頁面佈局 ...
1. ES6
1.1 let變數聲明以及聲明特性
聲明變數
let a;
let b, c, e;
let f = 100,
g = "紅石榴21",
h = [];
特性:
- 變數不能重覆聲明
let start = "許巍";
let start = "刀郎"; // 報錯
- 塊級作用域 全局、函數、eval
{
let str = "紅石榴21"
}
console.log(str); // str is not defined
不僅僅針對花括弧,if else while for中都是塊級作用域
- 不存在變數提升
console.log(song);
let song = "羅剎海市"; // Cannot access 'song' before initialization
- 不影響作用域鏈
{
let school = "國防科技大學";
function fn() {
console.log(school); // 國防科技大學
}
fn();
}
案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>let經典案例實踐</title> <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> </head> <body> <div class="container"> <h2 class="page-header">點擊切換顏色</h2> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div> <style> .item { width: 100px; height: 50px; border: solid 1px rgb(42, 156, 156); float: left; margin-right: 10px; } </style> <script> let items = document.getElementsByClassName("item"); // for (var i = 0; i < items.length; i++) { // items[i].onclick = function () { // this.style.background = "pink"; // for迴圈中,不使用let聲明 // }; // } for (let i = 0; i < items.length; i++) { items[i].onclick = function () { items[i].style.background = "pink"; // for迴圈中,使用let聲明 }; } </script> </body> </html>
1.2 const聲明常量以及特點
常量聲明const SCHOOL = "西南石油大學";特性:
- 一定要賦初始值
const A; // 報錯
- 一般變數使用大寫(潛規則)
const A = 100;
- 常量的值不能被修改
SCHOOL = "國防科技大學"; console.log(SCHOOL); // Assignment to constant variable.
- 塊級作用域
{ const YWZQ = "go"; } console.log(YWZQ); // YWZQ is not defined
- 對於數組和對象元素的修改,不算對常量的修改,不會報錯
const LIKE = ["HG", "MC", "LZZ"]; LIKE.push("ZZC"); console.log(LIKE); // ['HG', 'MC', 'LZZ', 'ZZC']
1.3 變數的解構賦值
ES6 允許按照一定模式從數組和對象中提取值,對變數進行賦值,這被稱為解構賦值。- 數組結構賦值
const F4 = ["小沈陽", "趙四", "劉能", "宋小寶"]; let [xiao, zhao, liu, song] = F4; console.log(xiao); // 小沈陽 console.log(zhao); // 趙四 console.log(liu); // 劉能 console.log(song); // 宋小寶
- 對象結構賦值
const zhao = { name: "趙本山", age: "65", xiaoping: function () { console.log("我會演小品"); }, }; let { name, age, xiaoping } = zhao; console.log(name); // 趙本山 console.log(age); // 65 console.log(xiaoping); // 輸出ƒ(){} xiaoping(); // 我會演小品如果不用結構的形式
console.log(zhao.name);
console.log(zhao.age);
zhao.xiaoping();
zhao.xiaoping();
1.4 模板字元串
ES6 引入新的聲明字元串的方式 『``』 '' ""- 聲明變數
let str = `今天天氣有點熱啊`;
console.log(str);
- 內容可以直接出現換行符
let str = "<ul>" + "<li>張三</li>" + "<li>李四</li>" + "<li>王五</li>" + "</ul>"; // 之前的寫法 let str = `<ul> <li>張三1</li> <li>李四2</li> <li>王五3</li> </ul>`; document.getElementById("appID").innerHTML = str;
- 字元串的拼接
let str = "許巍"; let lovest = `我喜歡${str}的歌,名字叫做<<藍蓮花>>。`; console.log(lovest);1.5 對象的簡化寫法 ES6 允許在大括弧裡面,直接寫入變數和函數,作為對象的屬性和方法。 這樣的書寫更加簡潔
let name = "紅石榴21"; let change = function () { console.log("我想改變世界!!"); }; const dream = { name, change, // improve: function () { // console.log("我又get到了新的技能!"); // }, // 簡寫形式 improve() { console.log("hahaha"); }, }; dream.change(); dream.improve();
1.6 箭頭函數以及聲明特點
ES6 允許使用「箭頭」(=>)定義函數。 聲明一個函數let fn = function() {} let fn = function (a, b) { return a + b; }; // 調用函數 let result = fn(1, 2); console.log(result); // 3
特性:
- this 是靜態的,this 始終指向函數聲明時所在作用域下的 this 的值
function getName() { console.log(this.name); } let getName2 = () => { console.log(this.name); }; // 設置 window 對象的name 屬性 window.name = "紅石榴21"; const school = { name: "博商學院", }; // 直接調用 getName(); // 紅石榴21 getName2(); // 紅石榴21 // call 方法調用 getName.call(school); // 博商學院 getName2.call(school); // 紅石榴21
- 不能作為構造函數實例化對象
let Person = (name, age) => { this.name = name; this.age = age; }; let me = new Person("hong", 18); console.log(me); // Person is not a constructor
- 不能使用 arguments 變數
let fn = () => { console.log(arguments); }; fn(1, 2, 3); // arguments is not defined
- 箭頭函數的簡寫
// 1) 省略小括弧,當形參有且只有一個的時候 let add = n => { return n + n; }; console.log(add(9)); // 18 // 2) 省略花括弧,當代碼體只有一條語句的時候,此時 return 必須省略 // 而且語句的執行結果就是函數的返回值 let pow = (n) => n * n; console.log(pow(9)); // 81
箭頭函數的實踐與應用場景
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>箭頭函數的實踐與應用場景</title> </head> <body> <div id="add"></div> <style> #add { width: 200px; height: 200px; background: #58a; } </style> <script> // 需求-1 點擊 div 2s 後顏色變成『粉色』 // 獲取元素 let add = document.getElementById("add"); //綁定事件 add.addEventListener("click", function () { // 1、setTimeout未使用箭頭函數 //保存 this 的值 // let _this = this; // let that = this; // let self = this; // setTimeout(function () { // _this.style.background = "pink"; // }, 2000); // 2、setTimeout使用箭頭函數, this 是靜態的 setTimeout(() => { this.style.background = "pink"; }, 2000); }); // 需求-2 從數組中返回偶數的元素 const arr = [1, 2, 4, 6, 10, 13]; // const result = arr.filter(function (item) { // if (item % 2 === 0) { // return true; // } else { // return false; // } // }); // const result = arr.filter((item) => { // if (item % 2 === 0) { // return true; // } else { // return false; // } // }); // 簡寫形式 const result = arr.filter((item) => item % 2 === 0); console.log(result); // 箭頭函數適合與 this 無關的回調,定時器,數組的方法回調 // 箭頭函數不適合與 this 有關的回調,事件回調,對象的方法 </script> </body> </html>1.7 函數參數的預設值設置 ES6 允許給函數參數賦值初始值
- 形參初始值 具有預設值的參數,一般位置要靠後(潛規則)
function add(a, b, c) { return a + b + c; } let result = add(1, 2, 3); console.log(result); // 6 // 設置預設值 function add(a, b, c = 4) { return a + b + c; } let result = add(1, 2); console.log(result); // 7
- 與結構賦值結合
function connect({ host, username, password, port }) { console.log(host); console.log(username); console.log(password); console.log(port); } connect({ host: "127.0.0.1", username: "admin", password: "admin", port: 80, });1.8 rest參數 ES6 引入 rest 參數,用於獲取函數的實參,用來代替 arguments ES5 獲取實參的方式
function date() { console.log(arguments); } date("俞老師", "王老師", "顧老師");
rest 參數
function date(...args) { console.log(args); // [俞老師", "王老師", "顧老師] 變成數組就可以使用 filter、some、every、map } date("俞老師", "王老師", "顧老師");rest 參數必須要放到參數最後
function fn(a, b, ...args) { console.log(a); // 1 console.log(b); // 2 console.log(args); // [3, 4, 5, 6] } fn(1, 2, 3, 4, 5, 6);
1.9 擴展運算符的介紹
『...』 擴展運算符能將『數組』轉換為逗號分隔的『參數序列』// 聲明一個數組 const tfbody = ["樸樹", "許巍", "刀郎"]; // 聲明一個函數 function likeSinger() { console.log(arguments); } likeSinger(...tfbody); console.log(tfbody);
輸出結果
擴展運算符的應用
- 數組的合併
const siDaTianWang = ["劉德華", "張學友", "郭富城", "黎明"]; const xiaoHuDui = ["吳奇隆", "陳志朋", "蘇有朋"]; // const zuHe = siDaTianWang.concat(xiaoHuDui); // 使用concat實現數組拼接 // console.log(zuHe); // ["劉德華", "張學友", "郭富城", "黎明","吳奇隆", "陳志朋", "蘇有朋"] const zuHe = [...siDaTianWang, ...xiaoHuDui]; console.log(zuHe); // ["劉德華", "張學友", "郭富城", "黎明","吳奇隆", "陳志朋", "蘇有朋"]
- 數組的克隆
const ziMu = ["A", "B", "C"]; const newArr = [...ziMu]; console.log(ziMu); // ["A", "B", "C"] console.log(newArr); // ["A", "B", "C"]
- 將偽數組轉為真正的數組
const divS = document.querySelectorAll("div"); const divArr = [...divS]; console.log(divArr);
輸出結果
1.10.1 Symbol的介紹與創建- 創建Symbol
let s = Symbol(); console.log(s, typeof s); // Symbol() 'symbol' let s2 = Symbol("嘀嘀咕咕"); let s3 = Symbol("嘀嘀咕咕"); console.log(s2, typeof s2); // Symbol(嘀嘀咕咕) 'symbol' console.log(s2 === s3); // false
- Symbol.for 創建
let s4 = Symbol.for("我的心思"); let s5 = Symbol.for("我的心思"); console.log(s4); // Symbol(我的心思) console.log(s4 === s5); // true
- 不能與其他數據進行運算
let result = s + 100; // Cannot convert a Symbol value to a number let result = s > 100; // Cannot convert a Symbol value to a number let result = s + s; // Cannot convert a Symbol value to a number // USONB you are so niubility // u undefined // s string symbol // o object // n null number // b boolean
1.10.2 對象添加Symbol類型的屬性
向對象中添加方法 up downlet game = { name: "學爸", up: function () {}, down: function () {}, }; // 聲明一個對象 let methods = { up: Symbol(), down: Symbol(), }; // console.log(methods); game[methods.up] = function () { console.log("我可以改變世界!"); }; game[methods.down] = function () { console.log("海鮮都留給小日子吃吧!"); }; console.log(game);
輸出結果
let phws = { name: "排核污水", [Symbol("say")]: function () { console.log("打斷小日子的狗腿"); }, [Symbol("woof")]: function () { console.log("小日子公開食海鮮,真香"); }, }; console.log(phws);
輸出結果
1.10.3 Symbol的內置屬性
- Symbol.hasInstance
class Person { static [Symbol.hasInstance](param) { console.log(param); console.log("我被用來檢測類型了"); return true; } } let o = {}; console.log(o instanceof Person);
- Symbol.isConcatSpreadable
const arr = [1, 2, 3]; const arr2 = [4, 5, 6]; arr2[Symbol.isConcatSpreadable] = false; console.log(arr.concat(arr2));
除了定義自己使用的 Symbol 值以外,ES6 還提供了 11個內置的 Symbol值,指向語言內部使用的方法。
1.11.1 迭代器介紹
迭代器(iterator)【對象中的一個屬性】是一種介面,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 iterator 介面,就可以完成遍歷操作。- ES6 創造了一種新的遍歷命令 for...of 迴圈,lterator 介面主要供 for...of 消費
- 原生具備 iterator 介面的數據(可用 for of 遍歷)
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList
- 工作原理
a) 創建一個指針對象,指向當前數據結構的起始位置
b) 第一次調用對象的 next 方法,指針自動指向數據結構的第一個成員
c) 接下來不斷調用 next 方法,指針一直往後移動,直到指向最後一個成員
d) 每調用 next 方法返回一個包含 value 和done 屬性的對象
註:需要自定義遍曆數據的時候,要想到迭代器。
// 聲明一個數組 const tangShengShiTu = ["唐僧", "孫悟空", "豬八戒", "沙和尚"]; // 使用 for...of 遍曆數組 // for (let v of tangShengShiTu) { // console.log(v); // "唐僧", "孫悟空", "豬八戒", "沙和尚" // } let iterator = tangShengShiTu[Symbol.iterator](); // 調用對象的next方法 console.log(iterator.next()); // {value: '唐僧', done: false} console.log(iterator.next()); // {value: '孫悟空', done: false} console.log(iterator.next()); // {value: '豬八戒', done: false} console.log(iterator.next()); // {value: '沙和尚', done: false} console.log(iterator.next()); // {value: '', done: true}
1.11.2 迭代器應用-自定義遍曆數據
// 聲明一個對象 const banJi = { name: "朗月班", stuList: ["xiaohong", "xiaolian", "xiaojia", "xiaoyuan"], [Symbol.iterator]() { // 索引變數 let index = 0; // let _this = this; // return { // next: function () { // if (index < _this.stuList.length) { // const result = { value: _this.stuList[index], done: false }; // // 下標自增 // index++; // // 返回結果 // return result; // } else { // return { value: _this.stuList[index], done: true }; // } // }, // }; // 使用箭頭函數 let next = () => { if (index < this.stuList.length) { const result = { value: this.stuList[index], done: false }; // 下標自增 index++; // 返回結果 return result; } else { return { value: this.stuList[index], done: true }; } }; return { next }; }, }; // 需求: 只能使用for of 遍歷stuList,通過面向對象 // 不能使用 banJi.stuList.forEach for (let v of banJi) { console.log(v); // "xiaohong", "xiaolian", "xiaojia", "xiaoyuan" }
1.12.1 生成器函數聲明與調用
生成器函數是 ES6 提供的一種非同步編程解決方案,語法行為與傳統函數完全不同
// 生成器其實就是一個特殊的函數 // 非同步編程 純回調函數 node fs ajax mongodb // 函數代碼的分隔符 function* gen() { console.log("hello generator"); // hello generator } let iterator = gen(); iterator.next();
另一個例子
function* gen() { console.log(111); yield "光輝歲月"; console.log(222); yield "藍蓮花"; console.log(333); yield "像風一樣自由"; console.log(444); } let iterator = gen(); console.log(iterator.next()); // 111 {value: '光輝歲月', done: false} console.log(iterator.next()); // 222 {value: '藍蓮花', done: false} console.log(iterator.next()); // 333 {value: '像風一樣自由', done: false} console.log(iterator.next()); // 444 {value: 'undefined', done: true} // 遍歷 for (let v of gen()) { console.log(v); }
遍歷輸出結果
1.12.2 生成器函數的參數傳遞
function* gen() { yield 111; yield 222; yield 333; } // 執行獲取迭代器對象 let iterator = gen(); console.log(iterator.next()); // {value: 111, done: false} console.log(iterator.next()); // {value: 222, done: false} console.log(iterator.next()); // {value: 333, done: false} console.log(iterator.next()); // {value: undefined, done: true}
另一個例子
function* gen(arg) { console.log(arg); let one = yield 111; console.log(one); let two = yield 222; console.log(two); let three = yield 333; console.log(three); } // 執行獲取迭代器對象 let iterator = gen("AAA"); console.log(iterator.next()); // next方法可以傳入實參 console.log(iterator.next("BBB")); // 第二次調用作為第一個yield的返回參數 console.log(iterator.next("CCC")); // 第三次調用作為第二個yield的返回參數 console.log(iterator.next("DDD")); // 第四次調用作為第三個yield的返回參數 console.log(iterator.next("FFF"));
輸出結果
1.12.3 生成器函數實例 非同步編程 文件操作 網路操作(ajax, request) 資料庫操作 需求-1 1s 後控制台輸出 111 2s 後控制台輸出 222 3s 後控制台輸出 333 // 這種調用方式叫做回調地獄setTimeout(() => { console.log(111); setTimeout(() => { console.log(222); setTimeout(() => { console.log(333); }, 3000); }, 2000); }, 1000);
另一個例子
function one() { setTimeout(() => { console.log(111); iterator.next(); }, 1000); } function two() { setTimeout(() => { console.log(222); iterator.next(); }, 2000); } function three() { setTimeout(() => { console.log(333); }, 3000); } function* gen() { yield one(); yield two(); yield three(); } // 調用生成器函數 let iterator = gen(); iterator.next();
輸出結果
1.12.4 生成器函數實例-2
需求-2 模擬獲取 先調用用戶數據,然後調用訂單數據,最後調用商品數據function getUsers() { setTimeout(() => { let data = "用戶數據"; console.log(data); iterator.next(); }, 1000); } function getOrders() { setTimeout(() => { let data = "訂單數據"; console.log(data); iterator.next(); }, 1000); } function getGoods() { setTimeout(() => { let data = "商品數據"; console.log(data); }, 1000); } function* gen() { yield getUsers(); yield getOrders(); yield getGoods(); } // 調用生成器函數 let iterator = gen(); iterator.next();
輸出結果
需求-2,補充調用傳參
function getUsers() { setTimeout(() => { let data = "用戶數據1"; iterator.next(data); }, 1000); } function getOrders() { setTimeout(() => { let data = "訂單數據2"; iterator.next(data); }, 1000); } function getGoods() { setTimeout(() => { let data = "商品數據3"; iterator.next(data); }, 1000); } function* gen() { let users = yield getUsers(); console.log(users); let orders = yield getOrders(); console.log(orders); let goods = yield getGoods(); console.log(goods); } // 調用生成器函數 let iterator = gen(); iterator.next();
輸出結果
1.13.1 Promise介紹與基本使用
Promise 是ES6引入的非同步編程的新解決方案。語法上 Promise 是一個構造函數用來封裝非同步操作並可以獲取其成功或失敗的結果。
- Promise構造函數:Promise(excutor)
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
// 實例化 Promise 對象 const p = new Promise(function (resolve, reject) { setTimeout(() => { // let data = "讀取用戶數據"; // resolve(data); let err = "讀取數據失敗!"; reject(err); }, 1000); }); // 調用 promise 對象的 then 方法 p.then( function (value) { console.log(value); // 讀取用戶數據 }, function (error) { console.error(error); // 讀取數據失敗! } );
1.13.2 Promise封裝讀取文件
// 1、引入 fs 模塊 const fs = require("fs"); // 2、調用方法讀取文件 // fs.readFile('./resources/為學.md', (err, data) => { // // 如果失敗,則拋出錯誤 // if (err) throw err; // // 如果沒有出錯,則輸出內容 // console.log(data.toString()); // }); // 3、使用 Promise 封裝 const p = new Promise(function (resolve, reject) { fs.readFile("./resources/為學.md", (err, data) => { // 判斷如果失敗 if (err) reject(err); // 如果成功 resolve(data); }); }); p.then(function (value) { console.log(value.toString()); }, function (err) { console.log("讀取失敗!!") })
輸出結果
1.13.3 Promise封裝AJAX請求
- 方法-1 普通寫法
// 介面地址: https://api.apiopen.top/api/getDynamic // 1、創建對象 const xhr = new XMLHttpRequest(); // 2、初始化 xhr.open("GET", "https://api.apiopen.top/api/getDynamic"); // 3、發送 xhr.send(); // 4、綁定事件,處理響應結果 xhr.onreadystatechange = function () { // 判斷 if (xhr.readyState === 4) { // 判斷響應狀態碼 200-299 if (xhr.status >= 200 && xhr.status < 300) { console.log(xhr.response); } else { // 如果失敗 console.log(xhr.status); } } };
- 方法-2 Promise封裝
const p = new Promise((resolve, reject) => { // 1、創建對象 const xhr = new XMLHttpRequest(); // 2、初始化 xhr.open("GET", "https://api.apiopen.top/api/getDynamic"); // 3、發送 xhr.send(); // 4、綁定事件,處理響應結果 xhr.onreadystatechange = function () { // 判斷 if (xhr.readyState === 4) { // 判斷響應狀態碼 200-299 if (xhr.status >= 200 && xhr.status < 300) { // 表示成功 resolve(xhr.response); } else { // 如果失敗 reject(xhr.status); } } }; }); // 指定回調 p.then( function (value) { console.log(value); }, function (error) { console.log(error); } );
1.13.4 Promise.prototype..then方法
// 創建 promise 對象 const p = new Promise((resolve, reject) => { setTimeout(() => { resolve("獲取用戶數據成功!"); }, 1000); }); // 調用 then 方法 then方法的返回結果是 Promise 對象,對象狀態由回調函數的執行結果決定 // 1、如果回調函數中返回的結果是 非 promise 類型的屬性, 狀態為成功,返回值為對象的成功的值 const result = p.then( (value) => { // console.log(value); // 1、非 promise 類型的屬性 return "I Love You"; // 2、是promise 對象 // return new Promise((resolve, reject) => { // resolve("ok"); // reject('error'); // }); // 3、拋出錯誤 // throw new Error("出錯啦!"); // throw '出錯啦!' }, (reason) => { console.error(reason); } ); console.log(result); // p.then( // (value) => { // console.log(value); // }, // (error) => { // console.log(error); // } // ); // 鏈式調用 p.then(value=>{ }).then(reason=>{ })
1.13.5 Promise實踐練習-多個文件內容讀取
- 方法-1 回調地獄
fs.readFile("./resources/為學.md", (err, data1) => { fs.readFile("./resources/插秧詩.md", (err, data2) => { fs.readFile("./resources/觀書有感.md", (err, data3) => { // let result = data1 + '\r\n' + data2 + '\r\n' + data3; let result = `${data1}\r\n${data2}\r\n${data3}` console.log(result); }) }) });
- 方法-2 使用 promise 實現
const p = new Promise((resolve, reject) => { fs.readFile("./resources/為學.md", (err, data) => { resolve(data); }) }); p.then(value => { return new Promise((resolve, reject) => { fs.readFile("./resources/插秧詩.md", (err, data) => { resolve([value, data]); }) }) }).then(value => { return new Promise((resolve, reject) => { fs.readFile("./resources/觀書有感.md", (err, data) => { // 壓入 value.push(data); resolve(value); }); }) }).then(value => { console.log(value.join('\r\n')); })
- 方法-3 使用生成器函數
function one() { fs.readFile("./resources/為學.md", (err, data) => { iterator.next(data); }) }