Javascript ES6-11
ECMS相關介紹
什麼是ECMA
ECMA(European Computer Manufacturers Association)中文名稱為歐洲計算機制
造商協會,這個組織的目標是評估、開發和認可電信和計算機標準。1994 年後該
組織改名為 Ecma 國際
什麼是ECMAScript
ECMAScript 是由 Ecma 國際通過 ECMA-262 標準化的指令碼程式設計語言。
什麼是ECMA-262
Ecma 國際制定了許多標準,而 ECMA-262 只是其中的一個,所有標準列表檢視
http://www.ecma-international.org/publications/standards/Standard.htm
ECMA-262歷史版本
ECMA-262(ECMAScript)歷史版本檢視網址
http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
- 從 ES6 開始,每年釋出一個版本,版本號比年份最後一位大 1
誰在維護 ECMA-262
TC39(Technical Committee 39)是推進 ECMAScript 發展的委員會。其會員都是
公司(其中主要是瀏覽器廠商,有蘋果、谷歌、微軟、因特爾等)。TC39 定期
召開會議,會議由會員公司的代表與特邀專家出席
ES6相容性
-
ES6 的版本變動內容最多,具有里程碑意義
-
ES6 加入許多新的語法特性,程式設計實現更簡單、高效
-
相容性
http://kangax.github.io/compat-table/es6/
ECMAScript 6
let變數宣告以及特性
- 宣告物件型別使用 const,非物件型別宣告選擇 let
變數不能重複宣告
//宣告變數
// let a;
// let b,c,d;
// let e = 100;
// let f = 521, g = 'iloveyou', h = [];
//1. 變數不能重複宣告
let star = '羅志祥';
let star = '小豬';
//Identifier 'star' has already been declared
塊級作用域
- 之前作用域: 全域性, 函式, eval(eveal,es5嚴格模式才出現)
- 現在引入塊級作用域if else while for 都是塊級作用域
// if else while for 都是塊級作用域
{
girl = '周揚青';
}
console.log(girl);
//girl is not defined
### 不存在變數提升
console.log(song);
let song = '戀愛達人';
// Cannot access 'song' before initialization
不影響作用域鏈
{
let school = 'wangkai';
function fn(){
console.log(school);
}
fn(); //wangkai
}
const宣告常量以及特點
-
值不能修改的量叫常量
-
宣告常量
const SCHOOL = '你好啊'; console.log(SCHOOL) //你好啊
一定要賦初始值
const A;
//Missing initializer in const declaration
一般常量使用大寫(潛規則)
onst a = 100;
常量的值不能修改
const SCHOOL = '你好啊';
SCHOOL = 'ABCD';
// console.log(SCHOOL) //Assignment to constant variable.
塊級作用域
{
const PLAYER = 'UZI';
}
console.log(PLAYER);
//PLAYER is not defined
改物件不會報錯
- 對於陣列和物件的元素修改, 不算做對常量的修改, 不會報錯
const TEAM = ['UZI','MXLG','Ming','Letme'];
// TEAM.push('Meiko');
變數的解構賦值
- ES6 允許按照一定模式從陣列和物件中提取值,對變數進行賦值,這被稱為解構賦值。
陣列的解構
const F4 = ['小瀋陽','劉能','趙四','宋小寶'];
let [xiao, liu, zhao, song] = F4;
console.log(xiao); //小瀋陽
console.log(liu); //劉能
console.log(zhao); //趙四
console.log(song); //宋小寶
### 物件的解構
const zhao = {
name: '趙本山',
age: '不詳',
xiaopin: function(){
console.log("我可以演小品");
}
};
let {name, age, xiaopin} = zhao;
console.log(name); //趙本山
console.log(age); //不詳
console.log(xiaopin);
//ƒ (){ console.log("我可以演小品");}
// xiaopin(); //我可以演小品
// 以前:zhao.xiaopin();
// zhao.xiaopin();
// zhao.xiaopin();
// zhao.xiaopin(); //我可以演小品
// 現在:
let {xiaopin} = zhao; //我可以演小品
xiaopin();
模板字串
``
- ES6引入了新的宣告方式``
- 以前:
''
和" "
let str = `我也是一個字串哦!`;
console.log(str, typeof str);
內容中可以直接出現換行
let str = `<ul>
<li>沈騰</li>
<li>瑪麗</li>
<li>魏翔</li>
<li>艾倫</li>
</ul>`;
console.log(str)
// <ul>
//<li>沈騰</li>
//<li>瑪麗</li>
//<li>魏翔</li>
//<li>艾倫</li>
//</ul>
變數拼接
let lovest = '魏翔';
let M = '呵呵呵'
let out = `${lovest}是我心目中最搞笑的演員${M}!!`;
console.log(out);
// 魏翔是我心目中最搞笑的演員呵呵呵!!
簡化物件寫法
- ES6 允許在大括號裡面,直接寫入變數和函式,作為物件的屬性和方法。這樣的書寫更加簡潔
let name = '尚矽谷';
let change = function(){
console.log('我們可以改變你!!');
}
const school = {
name, //屬性名和變數名一樣可以省略一個
change,
improve(){ //省略了function和:
console.log("我們可以提高你的技能");
}
}
console.log(school);
//{name: "尚矽谷", change: ƒ, improve: ƒ}
箭頭函式
宣告一個箭頭函式
- ES6 允許使用「箭頭」(=>)定義函式。
//宣告一個函式
// let fn = function(){
// } //以前
let fn = (a,b) => {
return a + b;
}
//呼叫函式
let result = fn(1, 2);
console.log(result); //3
箭頭函式的this
箭頭函式適合與 this 無關的回撥.
比如 :定時器, 陣列的方法回撥
頭函式不適合與 this 有關的回撥(只是說不適合)
事件回撥, 物件的方法
- this 是靜態的. this 始終指向函式宣告時所在作用域下的 this 的值
- 並沒有自己的this
function getName(){
console.log(this.name); //普通方式的函式
}
let getName2 = () => {
console.log(this.name); //箭頭函式
}
//設定 window 物件的 name 屬性
window.name = '尚矽谷';
const school = {
name: "ATGUIGU"
}
//直接呼叫
getName(); //尚矽谷
getName2(); //尚矽谷
//call 方法呼叫
getName.call(school); //ATGUIGU 改變
getName2.call(school); //尚矽谷 箭頭函式this靜態的,不會變
不能作為構造例項化物件
let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('xiao',30);
console.log(me);
//Person is not a constructor
### 不能使用arguments變數
let fn = () => {
console.log(arguments);
}
fn(1,2,3);//arguments is not defined
省略小括號
- 當形參有且只有一個的時候,可以省略小括號
let add = n => {
return n + n;
}
console.log(add(9)); //18
省略花括號
- 當程式碼體只有一條語句的時候可以省略花括號, 此時 return 必須省略
- 而且語句的執行結果就是函式的返回值
let pow = n => n * n;
console.log(pow(8)); //64
實踐
- 需求-1 點選 div 2s 後顏色變成『粉色』
//需求-1 點選 div 2s 後顏色變成『粉色』
//獲取元素
let ad = document.getElementById('ad');
//繫結事件
ad.addEventListener("click", function(){
//以前儲存 this 的值
// let _this = this;
//定時器
setTimeout(() => { //之前是function,現在是箭頭函式
//修改背景顏色 this
// console.log(this); //window
//this找不到就像外層找,儲存外部的this
// _this.style.background = 'pink';
this.style.background = 'pink';
//現在this指向外層作用域,外層的this指向ad
}, 2000);
});
- 從陣列中返回偶數的元素
const arr = [1,6,9,10,100,25];
// const result = arr.filter(function(item){
// if(item % 2 === 0){
// return true;
// }else{
// return false;
// }
// });
const result = arr.filter(item => item % 2 === 0);
console.log(result); //(3) [6, 10, 100]
允許設定引數預設值
形參初始值
- ES6 允許給函式引數賦值初始值
- 形參初始值 具有預設值的引數, 一般位置要靠後(潛規則)
function add(a,c=10,b) {
return a + b + c;
}
let result = add(1,2);
// console.log(result); //NaN 有預設值不會
與解構賦值結合
function connect({host="127.0.0.1", username,password, port}){
console.log(host) //atguigu.com
console.log(username) //root
console.log(password) //root
console.log(port) //3306
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306
})
rest引數
- ES6 引入 rest 引數,用於獲取函式的實參,用來代替 arguments
ES5 獲取實參的方式
- 返回的是物件
function date(){
console.log(arguments);
}
date('白芷','阿嬌','思慧');
// Arguments(3) ["白芷", "阿嬌", "思慧", callee: ƒ, Symbol(Symbol.iterator): ƒ]
rest 引數
- 返回的是陣列,可以對陣列用下面方法
- 可以用陣列的方法…filter some every map
function date(...args){
console.log(args);
//(3) ["阿嬌", "柏芝", "思慧"]
//返回的是陣列,可以對陣列用下面方法
// filter some every map
}
### rest引數必須要放到引數最後
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6); //1,2 (4) [3, 4, 5, 6]
spread擴充套件運算子
…擴充套件元素運算子
...
擴充套件運算子能將陣列轉換成為逗號分隔的引數序列
const tfboys = ['易烊千璽','王源','王俊凱'];
// => '易烊千璽','王源','王俊凱'
// 宣告一個函式
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千璽','王源','王俊凱')
//rest ...是放在了形參,而這個是實參
------擴充套件運算子的應用------
陣列的合併
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang); //以前方法
//(4) ["王太利", "肖央", "曾毅", "玲花"]
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);
// //(4) ["王太利", "肖央", "曾毅", "玲花"]
陣列的克隆
- 是一個淺拷貝
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua];
console.log(sanyecao);// ['E','G','M']
### 將偽陣列轉為真正的陣列
const divs = document.querySelectorAll('div');
console.log(divs);
// __proto__(Nodelist).__proto__ (Object)
const divArr = [...divs];
console.log(divArr);
//__proto__(Array).__proto__ (Object)
Symbol
ES6 引入了一種新的原始資料型別 Symbol,表示獨一無二的值。它是JavaScript 語言的第七種資料型別,是一種類似於字串的資料型別。
symbol特點
- Symbol 的值是唯一的,用來解決命名衝突的問題
- Symbol 值不能與其他資料進行運算
Symbol 定義 的 物件屬 性 不能 使 用 for…in 循 環遍 歷 ,但 是可 以 使 用Reflect.ownKeys 來獲取物件的所有鍵名
- 遇到唯一性的場景時要想到 Symbol
建立Symbol
let s = Symbol(); //函式
console.log(s, typeof s);
//Symbol() "symbol"
Symbol唯一性
let s2 = Symbol('尚矽谷');
let s3 = Symbol('尚矽谷');
// console.log(s2 === s3) //false
Symbol.for建立
let s4 = Symbol.for('尚矽谷'); //函式物件
let s5 = Symbol.for('尚矽谷');
console.log(s4,typeof s4)
//Symbol(尚矽谷) "symbol"
// console.log(s4 === s5) //true
不能與其他資料進行運算
let result = s + 100;
let result = s > 100;
let result = s + s;
//Identifier 'result' has already been declared
七種資料型別
USONB you are so niubility
u undefined
s string symbol
o object
n null number
b boolean
------❥給物件新增Symbol屬性的兩種方式❥------
Symbol作用 給物件新增屬性和方法(獨一無二)
第一種
//向物件中新增方法 up down
let game = {
name:'俄羅斯方塊',
up: function(){},
down: function(){}
};
//宣告一個物件
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function(){
console.log("我可以改變形狀");
}
game[methods.down] = function(){
console.log("我可以快速下降!!");
}
console.log(game);
//{name: "俄羅斯方塊", up: ƒ, down: ƒ, Symbol(): ƒ, Symbol(): ƒ}
第二種
let youxi = {
name:"狼人殺",
[Symbol('say')]: function(){
console.log("我可以發言")
},
[Symbol('zibao')]: function(){
console.log('我可以自爆');
}
}
console.log(youxi)
//{name: "狼人殺", Symbol(say): ƒ, Symbol(zibao): ƒ}
------❥Symbol內建屬性❥------
Symbol.hasInstance
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用來檢測型別了");
return false;
}
}
let o = {};
console.log(o instanceof Person);
// {}
//我被用來檢測型別了
//false
Symbol.isConcatSpreadable
const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
//(4) [1, 2, 3, Array(3)]
Iterator 迭代器
- 需要自定義遍歷資料的時候,要想到迭代器。
遍歷器(Iterator)就是一種機制。它是一種介面,為各種不同的資料結構提供統一的訪問機制。任何資料結構只要部署 Iterator 介面,就可以完成遍歷操作。
-
Iterator介面 就是物件裡的一個屬性,這個屬性的名字叫做[Symbol.iterator]
-
ES6 創造了一種新的遍歷命令 for…of 迴圈,Iterator 介面主要供 for…of 消費
-
原生具備 iterator 介面的資料(可用 for of 遍歷)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
for…of 遍歷陣列
//宣告一個陣列
const xiyou = ['唐僧','孫悟空','豬八戒','沙僧'];
// 使用 for...of 遍歷陣列
for(let v of xiyou){
console.log(v); //唐僧 孫悟空 豬八戒 沙僧
}
console.log(xiyou)
//[(4) ["唐僧", "孫悟空", "豬八戒", "沙僧"].__proto__
//Symbol(Symbol.iterator): ƒ values()]
迭代器工作原理
- 建立一個指標物件,指向當前資料結構的起始位置
- 第一次呼叫物件的 next 方法,指標自動指向資料結構的第一個成員
- 接下來不斷呼叫 next 方法,指標一直往後移動,直到指向最後一個成員
- 每呼叫 next 方法返回一個包含 value 和 done 屬性的物件
const xiyou = ['唐僧','孫悟空','豬八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
// console.log(iterator)
//Array Iterator {}.__proto__
//next: ƒ next()
//呼叫物件的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:
//undefined, done: true} true表示遍歷迴圈完成
自定義迭代器遍歷物件
//宣告一個物件
const banji = {
name: "終極一班",
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
// 加上Iterator介面(方法)
[Symbol.iterator]() {
//索引變數
let index = 0;
//
let _this = this;
//返回一個物件(對應1.建立一個指標物件,指向當前資料結構的起始位置)
return {
//新增next方法(對應4.每呼叫 next 方法返回一個包含 value 和 done 屬性的物件)
next: function () {
if (index < _this.stus.length) {
const result = { value: _this.stus[index], done: false };
//下標自增
index++;
//返回結果
return result;
}else{
return {value: undefined, done: true};
}
}
};
}
}
//遍歷這個物件
for (let v of banji) {
console.log(v); //xiaoming,xiaoning,xiaotian,knight
}
生成器函式
- 生成器函式是 ES6 提供的一種非同步程式設計解決方案
生成器本身是一個函式
生成器函式是 ES6 提供的一種非同步程式設計解決方案,語法行為與傳統函式完全不同
生成器其實就是一個特殊的函式(宣告特殊,執行特殊,調next方法才執行)
非同步程式設計 純回撥函式 node fs ajax mongodb
yield算作函式程式碼的分隔符
生成器函式的宣告
- 程式碼說明
- * 的位置沒有限制
- 生成器函式返回的結果是迭代器物件,呼叫迭代器物件的 next 方法可以得到yield 語句後的值
- yield 相當於函式的暫停標記,也可以認為是函式的分隔符,每呼叫一次 next方法,執行一段程式碼
- next 方法可以傳遞實參,作為 yield 語句的返回值
function * gen(){
console.log(111);
yield '一隻沒有耳朵';
//(yield後面跟表示式或者跟字面量)
console.log(222);
yield '一隻沒有尾部';
console.log(333);
yield '真奇怪';
console.log(444);
}
// let iterator = gen();
// iterator.next(); //111
// iterator.next(); //222
// iterator.next(); //333
// iterator.next(); //444
// 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);
}
//111
//一隻沒有耳朵
//222
//一隻沒有尾部
//333
//真奇怪
//444
### 生成器函式的呼叫
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}
生成器函式傳參
- 生成器整體函式傳參
- next方法也是可以傳參的(實參),而且我們這個方法(實參)作為上一個yield語句的返回結果
- 第二次呼叫next,yield傳入的引數作為第一個yield語句整體返回結果
function * gen(arg) {
console.log(arg) //undefined
let one = yield 111;
console.log(one) //BBB
let two = yield 222;
console.log(two)//CCC
let three = yield 333;
console.log(three)//DDD
}
let iterator = gen() //undefined
console.log(iterator.next('kkk'))
//經過測試,第一次傳參無用
//{value: 111, done: false}
console.log(iterator.next('BBB'))
//{value: 222, done: false}
console.log(iterator.next('CCC'))
//{value: 333, done: false}
console.log(iterator.next('DDD'))
//{value: undefined, done: true}
回撥地獄
非同步程式設計:比如: 1.檔案操作 2.網路操作(ajax, request) 3.資料庫操作
- 需求:1s後控制檯輸出 111 2s後輸出 222 3s後輸出 333
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 3000);
}, 2000);
}, 1000);
生成器函式解決回撥地獄
需求: 1s後控制檯輸出 111 2s後輸出 222 3s後輸出 333
- 生成器函式解決
- 宣告三個函式.分別完成三個非同步任務
//輸出1任務
function one(){
setTimeout(()=>{
console.log(111);
iterator.next();
},1000)
}
//第二個非同步任務
function two(){
setTimeout(()=>{
console.log(222);
iterator.next();
},2000)
}
//第三個非同步任務
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();
},3000)
}
function * gen(){
yield one();
yield two();
yield three();
}
//呼叫生成器函式
let iterator = gen();
iterator.next();
// 不在任務重加iterator.next()只輸出111
//111/222/333
生成器函式在非同步任務的表現
- 模擬獲取 使用者資料 訂單資料 商品資料
function getUsers(){
setTimeout(()=>{
let data = '使用者資料';
//呼叫 next 方法, 並且將資料傳入
iterator.next(data);
}, 1000);
}
function getOrders(){
setTimeout(()=>{
let data = '訂單資料';
iterator.next(data);
}, 1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品資料';
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();
Promise
Promise 是 ES6 引入的非同步程式設計的新解決方案(主要解決回撥地獄問題)。語法上 Promise 是一個建構函式,用來封裝非同步操作並可以獲取其成功或失敗的結果。
例項化Promise物件
- 成功狀態
const p = new Promise(function(resolve,reject) {
setTimeout(function() {
let data = '資料庫中的使用者資料';
// 呼叫resovle方法
resolve(data)
//呼叫resolve函式以後,這個Promise物件狀態就會變為成功
//物件有三個狀態: 初始化 成功 失敗
},1000);
});
//呼叫promise物件的then方法
//成功的形參叫value,失敗的形參叫reason
p.then(function(value){
console.log(value); //資料庫中的資料
},function(){
})
- 失敗狀態
const p = new Promise(function(resolve,reject) {
setTimeout(function() {
let data = '資料庫中的使用者資料';
// 呼叫resovle方法
reject(data)
//呼叫resolve函式以後,這個Promise物件狀態就會變為成功
//物件有三個狀態: 初始化 成功 失敗
},1000);
});
//呼叫promise物件的then方法
//成功的形參叫value,失敗的形參叫reason
p.then(function(value){
console.log(value); //資料庫中的資料
},function(reason){
console.error(reason); //資料庫中的使用者資料
})
Promise封裝讀取檔案
- 呼叫方法讀取檔案
//1. 引入 fs 模組
const fs = require('fs');
fs.readFile('./resources/為學.md', (err, data)=>{
//如果失敗, 則丟擲錯誤
if(err) throw err;
//如果沒有出錯, 則輸出內容
// console.log(data); //buffer
console.log(data.toString()); //一首詩
});
- 使用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(reason){
console.log("讀取失敗!!");
});
Promise封裝AJAX
- 傳送ajax請求
<script>
// 介面地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {
//1. 建立物件
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJok(e)");
//3. 傳送
xhr.send();
//4. 繫結事件, 處理響應結果
xhr.onreadystatechange = function () {
//判斷
if (xhr.readyState === 4) {
//判斷響應狀態碼 200-299
if (xhr.status >= 200 && xhr.status < 300) {
//表示成功
// console.log(xhr.response); 文字
resolve(xhr.response);
} else {
//如果失敗
// console.error(xhr.status); 404
reject(xhr.status);
}
}
}
})
//指定回撥
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
});
</script>
Promise.prototype.then
<script>
//建立 promise 物件
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('使用者資料');
// reject('出錯啦');
}, 1000)
});
// 呼叫then方法
const result = p.then(value => {
console.log(value);
return '王凱';
},reason => {
console.warn(reason);
})
console.log(result)
//Promise {<pending>}
// __proto__: Promise
//[[PromiseStatus]]: "fulfilled"
//[[PromiseValue]]: undefined
//呼叫 then 方法 then方法的返回結果是 Promise 物件, 物件狀態由回撥函式的執行結果決定
//1. 如果回撥函式中返回的結果是 非 promise 型別的屬性, 狀態為成功, 返回值為物件的成功的值
// const result = p.then(value => {
// console.log(value);
// //1. 非 promise 型別的屬性
// // return 'iloveyou';
// //2. 是 promise 物件
// // return new Promise((resolve, reject)=>{
// // // resolve('ok'); then方法就chegng,返回值then成功的值
// // reject('error'); //then方法就失敗,返回的值就是then方法的值
// // });
// //3. 丟擲錯誤
// // throw new Error('出錯啦!');
// throw '出錯啦!';
// }, reason=>{
// console.warn(reason);
// });
//鏈式呼叫 then方法可以返回一個promise物件,所以可以鏈式呼叫
// p.then(value=>{
// }).then(value=>{
// });
</script>
實踐–讀取多個檔案
//引入 fs 模組
const fs = require("fs");
// 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;
// console.log(result); //三首詩拼接一起
// });
// });
// });
//使用 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')); //三首詩
});
Promise-catch方法
<script>
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
//設定 p 物件的狀態為失敗, 並設定失敗的值
reject("出錯啦!");
}, 1000)
});
// p.then(function(value){}, function(reason){
// console.error(reason);
// });
p.catch(function(reason){
console.warn(reason);
});
</script>
Set 集合
ES6 提供了新的資料結構 Set(集合)。它類似於陣列,但成員的值都是唯一的,集合實現了 iterator 介面,所以可以使用『擴充套件運算子』和『for…of…』進行遍歷,集合的屬性和方法:
### new Set()
- 宣告set
let s = new Set();
console.log(s,typeof s)
//Set(0) "object"
set會自動去重
s2 = new Set(['大事兒','小事兒','好事兒','壞事兒','小事兒']);
console.log(s2)
//它會自動去重
//Set(4) {"大事兒", "小事兒", "好事兒", "壞事兒"}
.size
- 元素的個數
- 返回集合的元素個數
console.log(s2.size);
//4
.add()
- 新增元素
- 增加一個新元素,返回當前集合
s2.add('喜事兒');
console.log(s2)
//Set(5) {"大事兒", "小事兒", "好事兒", "壞事兒", "喜事兒"}
.delete()
- 刪除元素
- 刪除元素,返回boolean值
s2.delete('壞事兒');
console.log(s2)
//Set(4) {"大事兒", "小事兒", "好事兒", "喜事兒"}
.has()
- 檢測
- 檢測集合中是否包含某個元素,返回 boolean 值
console.log(s2.has('糟心事'));
// false
.clear()
- 清空
- 清空集合,返回 undefined
// s2.clear();
// console.log(s2);
//Set(0) {}
for…of
for(let v of s2){
console.log(v);
}
//大事兒, 小事兒, 好事兒, 喜事兒
❥集合實踐❥(
陣列去重
let arr = [1,2,3,4,5,4,3,2,1];
let result = [...new Set(arr)];
console.log(result);
//(5) [1, 2, 3, 4, 5]
交集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => {
let s2 = new Set(arr2);// 4 5 6
if(s2.has(item)){
return true;
}else{
return false;
}
});
// console.log(result) //(2) [4, 5]
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// console.log(result); // 4 5
並集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let union = [...new Set([...arr, ...arr2])];
console.log(union);
//[1, 2, 3, 4, 5, 6]
差集(和交集相反)
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
//(3) [1, 2, 3]
Map
- 升級版的物件
ES6 提供了 Map 資料結構。它類似於物件,也是鍵值對的集合。但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當作鍵。Map 也實現了iterator 介面,所以可以使用『擴充套件運算子』和『for…of…』進行遍歷。
new Map()
- 宣告Map
let m = new Map();
console.log(m)
//Map(0) {}
.set()
- 增加一個新元素,返回當前 Map
m.set('name','尚矽谷');
console.log(m)
//Map(1) {"name" => "尚矽谷"}
//key: "name"
//value: "尚矽谷"
m.set('change', function(){
console.log("我們可以改變你!!");
});
//{"change" => function(){ console.log("我們可以改變你!!"); }}
//key: "change"
let key = {
school : 'ATGUIGU'
};
m.set(key, ['北京','上海','深圳']);
//key: {school: "ATGUIGU"}
//value: (3) ["北京", "上海", "深圳"]
.size
- 返回Map的元素個數
console.log(m.size);
//3
.delte()
- 刪除
m.delete('name');
console.log(m)
//Map(2) {"change" => ƒ, {…} => Array(3)}
.get()
- 返回鍵名物件的鍵值
console.log(m.get('change'));
//ƒ (){
//console.log("我們可以改變你!!");
//}
console.log(m.get(key));
//(3) ["北京", "上海", "深圳"]
.has()
- 檢測 Map 中是否包含某個元素,返回 boolean 值
.clear()
- 清空集合,返回 undefined
m.clear();
//Map(0){}
for…of
for(let v of m){
console.log(v);
}
// console.log(m);
//(2) ["name", "尚矽谷"]
//Map.html:65 (2) ["change", ƒ]
//Map.html:65 (2) [{…}, Array(3)]
class 類
- class 宣告類
- constructor 定義建構函式初始化
- extends 繼承父類
- super 呼叫父級構造方法
- static 定義靜態方法和屬性
- 父類方法可以重寫
ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,作為物件的模板。通過 class 關鍵字,可以定義類。基本上,ES6 的 class 可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的 class 寫法只是讓物件原型的寫法更加清晰、更像物件導向程式設計的語法而已
- ES5例項化物件
//ES5 例項化物件
//手機 例項物件的屬性初始化
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
//新增方法
Phone.prototype.call = function(){
console.log("我可以打電話!!");
}
//例項化物件
let Huawei = new Phone('華為', 5999);
Huawei.call(); //我可以打電話!!
console.log(Huawei);
//Phone brand: "華為" price: 5999 __proto__: Object
宣告class
- 構造方法 名字不能修改 必須叫constructor
- 使用new加型別的時候,會自動執行例項物件上的constructor方法
- 方法必須使用該語法, 不能使用 ES5 的物件完整形式
- 方法名+()+{} 沒有function 和 :
class Shouji{
//構造方法 名字不能修改 必須叫constructor
//使用new加型別的時候,會自動執行例項物件上的constructor方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必須使用該語法, 不能使用 ES5 的物件完整形式
//方法名+()+{} 沒有function 和 :
call(){
console.log("我可以打電話!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
//Shouji {brand: "1+", price: 1999} brand: "1+" price: 1999 __proto__: Object
static 類的靜態成員
- 靜態屬性
- static標註的屬性和方法它屬於類而不屬於例項物件
class Phone{
//靜態屬性
//static標註的屬性和方法它屬於類而不屬於例項物件
static name = '手機';
static change(){
console.log("我可以改變世界");
}
}
let nokia = new Phone();
console.log(nokia.name); //undefined
console.log(Phone.name); //手機
- ES5裡面
- 例項物件是例項物件 函式物件是函式物件 他們的屬性是不通的
- 實力物件裡面的屬性 和函式物件裡面的屬性是不通的
function Phone(){
}
Phone.name = '手機';
Phone.change = function(){
console.log("我可以改變世界");
}
//上面這些屬性屬於函式物件的,並不屬於例項物件 稱為靜態成員
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(nokia.name);
//undefined
nokia.change();
console.log(nokia.size);
//nokia.change is not a function
console.log(nokia.size)
//5.5inch
ES5類繼承
//手機
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function(){
console.log("我可以打電話");
}
//智慧手機
function SmartPhone(brand, price, color, size){
Phone.call(this, brand, price);
//this指向SmartPhone裡面的this,也就是SmartPhone例項化物件
this.color = color;
this.size = size;
}
//為了實現繼承 設定子級建構函式的原型
SmartPhone.prototype = new Phone;
// 不加也行
SmartPhone.prototype.constructor = SmartPhone;
//宣告子類的方法
SmartPhone.prototype.photo = function(){
console.log("我可以拍照")
}
SmartPhone.prototype.playGame = function(){
console.log("我可以玩遊戲");
}
const chuizi = new SmartPhone('錘子',2499,'黑色','5.5inch');
console.log(chuizi);
extends 繼承父類
- extends 繼承父類
<script>
class Phone{
//構造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父類的成員屬性
call(){
console.log("我可以打電話!!");
}
}
class SmartPhone extends Phone {
//構造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩遊戲");
}
call(){
console.log('我可以進行視訊通話');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
</script>
子類是不能呼叫父類的同名方法的
<script>
//js語法裡子類是不能呼叫父類的同名方法的
class Phone{
//構造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父類的成員屬性
call(){
console.log("我可以打電話!!");
}
}
class SmartPhone extends Phone {
//構造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩遊戲");
}
call(){
console.log('我可以進行視訊通話');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
</script>
class的set 和 get
<script>
// get 和 set
class Phone{
get price(){
console.log("價格屬性被讀取了");
return 'iloveyou';
}
set price(newVal){
console.log('價格屬性被修改了');
}
}
//例項化物件
let s = new Phone();
// console.log(s.price);
s.price = 'free';
</script>
數值擴充套件
Number.EPSILON
- Number.EPSILON 是 JavaScript 表示的最小精度
- EPSILON 屬性的值接近於 2.2204460492503130808472633361816E-16
function equal(a, b){
if(Math.abs(a-b) < Number.EPSILON){
return true;
}else{
return false;
}
}
// console.log(0.1 + 0.2 === 0.3); false
// console.log(equal(0.1 + 0.2, 0.3)) //true
0b 0o
- ES6 提供了二進位制和八進位制數值的新的寫法,分別用字首 0b 和 0o 表示。
//1. 二進位制和八進位制
let b = 0b1010; //10
let o = 0o777; //511
let d = 100; //100
let x = 0xff; //255
// console.log(x);
Number.isFinite()
- 用來檢查一個數值是否為有限數
nsole.log(Number.isFinite(100)); //true
console.log(Number.isFinite(100/0)); //false
console.log(Number.isFinite(Infinity)); //false
Number.isNaN()
- 用來檢查一個值是否為 NaN
console.log(Number.isNaN(123)); //false
Number.parseInt()
- ES6 將全域性方法 parseInt 和 parseFloat,移植到 Number 物件上面,使用不變。
console.log(Number.parseInt('5211314love')); //5211314
Number.parseFloat()
console.log(Number.parseFloat('3.1415926神奇')); //3.1415926
Math.trunc()
- 用於去除一個數的小數部分,返回整數部分。
console.log(Math.trunc(3.5)); //3
Number.isInteger()
- 用來判斷一個數值是否為整數
console.log(Number.isInteger(5)); //true
console.log(Number.isInteger(2.5)); //false
Math.sign()
- 判斷一個數到底為正數 負數 還是零
console.log(Math.sign(100)); //1
console.log(Math.sign(0)); //0
console.log(Math.sign(-20000)); //-1
物件方法擴充套件
ES6 新增了一些 Object 物件的方法
- Object.is 比較兩個值是否嚴格相等,與『===』行為基本一致(+0 與 NaN)
- Object.assign 物件的合併,將源物件的所有可列舉屬性,複製到目標物件
- proto、setPrototypeOf、 setPrototypeOf 可以直接設定物件的原型
Object.is
- 判斷兩個值是否完全相等
console.log(Object.is(120, 120));// 類似於=== true
console.log(Object.is(NaN, NaN));// 區別=== true
console.log(NaN === NaN);// === //false
Object.assign
- 物件的合併 同名有的覆蓋,沒有的新增
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: 'atguigu.com',
pass: 'iloveyou',
test2: 'test2'
}
console.log(Object.assign(config1, config2));
//{host: "http://atguigu.com", port: 33060, name: "atguigu.com", pass: "iloveyou", test: "test", …}
Object.setPrototypeOf
- 設定原型物件,並不建議這樣去做
const school = {
name: '尚矽谷'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);//{xiaoqu: Array(3)}
- Object.getPrototypeof
模組化
模組化是指將一個大的程式檔案,拆分成許多小的檔案,然後將小檔案組合起來
模組化的好處
- 防止命名衝突
- 程式碼複用
- 高維護性
模組化規範產品
- ES6之前的模組化規範有
CommonJS | NodeJS、Browserify |
---|---|
AMD | requireJS |
CMD | seaJS |
使用ES6模組化引入模組
❥通用的匯入方式❥
- 瀏覽器使用ES6模組化引入模組
<script type="module">
//引入wk.js模組內容
import * as wk from './wk.js'
console.log(wk);
</script>
export 分別暴露
export let name = 'wangkai';
export function home() {
console.log('萬科歡迎您');
}
<script type="module">
//引入wk.js模組內容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //萬科歡迎您
</script>
export{} 統一暴露
let name = 'wangkai';
function home() {
console.log('萬科歡迎您');
}
export{name,home}
<script type="module">
//引入wk.js模組內容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //萬科歡迎您
</script>
export default{} 預設暴露
- 花括號裡面可以使任意型別 值
- 呼叫方法需要將加default : xxx.default.xxx()
export default{
name : 'wangkai',
home:function() {
console.log('萬科歡迎您');
}
}
<script type="module">
//引入wk.js模組內容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //萬科歡迎您
</script>
### ❥解構賦值形式引入❥
export 分別暴露
import {name,home} from './wk.js';
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('萬科歡迎您');}
export let name = 'wangkai';
export function home() {
console.log('萬科歡迎您');
}
export{} 統一暴露
- Identifier ‘name’ has already been declared
- 使用as 加別名,就不會和上面name衝突
import {name as namee,house} from './wkk.js';
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('萬科歡迎您');}
let name = 'wangkai';
function home() {
console.log('萬科歡迎您');
}
export{name,home}
export default{} 預設暴露
//default必須使用別名
import {default as kgg} from './wkkk.js';
console.log(kgg); //{name: "wangkai", home: ƒ}
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('萬科歡迎您');}
- 花括號裡面可以使任意型別 值
- 呼叫方法需要將加default : xxx.default.xxx()
export default{
name : 'wangkai',
home:function() {
console.log('萬科歡迎您');
}
}
簡便形式,只能針對預設形式
import wkkk from './wkkk.js';
console.log(wkkk); //{name: "wangkai", home: ƒ}
單獨建立一個文件
- html
<script src="./app.js" type="module"></script>
- js
// 入口檔案
// 模組引入
import * as wk from './wk.js';
import * as wkk from './wkk.js';
import * as wkkk from './wkkk.js';
console.log(wk);
console.log(wkk);
console.log(wkkk);
ES6-ES6模組化引入NPM包
<!--
1. 安裝工具 npm i babel-cli babel-preset-env browserify(webpack) -D
2. 編譯 npx babel src/js -d dist/js --presets=babel-preset-env
3. 打包 npx browserify dist/js/app.js -o dist/bundle.js
-->
//修改背景顏色為粉色
import $ from 'jquery';// const $ = require("jquery");
$('body').css('background','pink');
ECMAScript7
.includes
- Array.prototype.includes
- Includes 方法用來檢測陣列中是否包含某個元素,返回布林型別值
// includes indexOf(以前用indexOf)
const mingzhu = ['西遊記','紅樓夢','三國演義','水滸傳'];
//判斷
console.log(mingzhu.includes('西遊記'));
//true
console.log(mingzhu.includes('金瓶梅'));
//false
** 冪運算子
- 在 ES7 中引入指數運算子「**」,用來實現冪運算,功能與 Math.pow 結果相同
console.log(2 ** 10);// 1024
//效果一樣的 **更簡單
console.log(Math.pow(2, 10));//1024
ECMAScript8
- async 和 await 兩種語法結合可以讓非同步程式碼像同步程式碼一樣
async 函式
- async用來宣告一個特殊的函式
- async 函式的返回值為 promise 物件,
- promise 物件的結果由 async 函式執行的返回值決定
<script>
async function fn(){
// 返回一個字串
// return '尚矽谷';
// 返回的結果不是一個 Promise 型別的物件, 返回的結果就是成功 Promise 物件
// return;
//丟擲錯誤, 返回的結果是一個失敗的 Promise
// throw new Error('出錯啦!');
//返回的結果如果是一個 Promise 物件
return new Promise((resolve, reject)=>{
resolve('成功的資料');
// reject("失敗的錯誤");
});
}
const result = fn();
//呼叫 then 方法
result.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
</script>
await 表示式
- await 必須寫在 async 函式中
- await 右側的表示式一般為 promise 物件
- await 返回的是 promise 成功的值
- await 的 promise 失敗了, 就會丟擲異常, 需要通過 try…catch 捕獲處理
//建立 promise 物件
const p = new Promise((resolve, reject) => {
// resolve("使用者資料");
reject("失敗啦!");
})
// await 要放在 async 函式中.
async function main() {
// let result = await p;
// console.log(result) //使用者資料
try {
let result = await p; //使用者資料
//
console.log(result);
} catch (e) {
console.log(e); //失敗啦!
}
}
//呼叫函式
main();
async和await結合讀取檔案
//1. 引入 fs 模組
const fs = require("fs");
//讀取『為學』
function readWeiXue() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/為學.md", (err, data) => {
//如果失敗
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readChaYangShi() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧詩.md", (err, data) => {
//如果失敗
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readGuanShu() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/觀書有感.md", (err, data) => {
//如果失敗
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
//宣告一個 async 函式
async function main(){
//獲取為學內容
let weixue = await readWeiXue();
//獲取插秧詩內容
let chayang = await readChaYangShi();
// 獲取觀書有感
let guanshu = await readGuanShu();
console.log(weixue.toString());
console.log(chayang.toString());
console.log(guanshu.toString());
}
main();
async和await封裝AJAX請求
<script>
// 傳送 AJAX 請求, 返回的結果是 Promise 物件
function sendAJAX(url) {
return new Promise((resolve, reject) => {
//1. 建立物件
const x = new XMLHttpRequest();
//2. 初始化
x.open('GET', url);
//3. 傳送
x.send();
//4. 事件繫結
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//成功啦
resolve(x.response);
}else{
//如果失敗
reject(x.status);
}
}
}
})
}
//promise then 方法測試
// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{
// console.log(value);
// }, reason=>{})
// async 與 await 測試 axios
async function main(){
//傳送 AJAX 請求
let result = await sendAJAX("https://api.apiopen.top/getJoke");
//再次測試
let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')
console.log(tianqi);
}
main();
</script>
//宣告物件
const school = {
name:"尚矽谷",
cities:['北京','上海','深圳'],
xueke: ['前端','Java','大資料','運維']
};
//獲取物件所有的鍵
console.log(Object.keys(school));
//0: "name"1: "cities"2: "xueke"
Object.values
- Object.values()方法返回一個給定物件的所有可列舉屬性值的陣列
//獲取物件所有的值
// console.log(Object.values(school));
//["尚矽谷", Array(3), Array(4)]
Object.entries
- Object.entries()方法返回一個給定物件自身可遍歷屬性 [key,value] 的陣列
console.log(Object.entries(school));
// (3) [Array(2), Array(2), Array(2)]
// 0: (2) ["name", "尚矽谷"]
// 1: (2) ["cities", Array(3)]
// 2: (2) ["xueke", Array(4)]
//建立 Map
// const m = new Map(Object.entries(school));
// console.log(m.get('cities'));
Object.getOwnPropertyDescriptors
- Object.getOwnPropertyDescriptors
- 該方法返回指定物件所有自身屬性的描述物件
//物件屬性的描述物件
console.log(Object.getOwnPropertyDescriptors(school));
//{name: {…}, cities: {…}, xueke: {…}}
// const obj = Object.create(null, {
// name: {
// //設定值
// value: '尚矽谷',
// //屬性特性
// writable: true,
// configurable: true,
// enumerable: true
// }
// });
ECMAScript9
Rest/Spread屬性
- Rest 引數與 spread 擴充套件運算子在 ES6 中已經引入,不過 ES6 中只針對於陣列,在 ES9 中為物件提供了像陣列一樣的 rest 引數和擴充套件運算子
//rest 引數
function connect({host, port, ...user}){
console.log(host); //127.0.0.1
console.log(port); //3306
console.log(user); //{username: "root", password: "root", type: "master"}
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
物件合併
const skillOne = {
q: '天音波'
}
const skillTwo = {
w: '金鐘罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龍擺尾'
}
const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng)
//{q: "天音波", w: "金鐘罩", e: "天雷破", r: "猛龍擺尾"}
// ...skillOne => q: '天音波', w: '金鐘罩'
正則命名分組
let str = '<a href="http://www.atguigu.com">尚矽谷</a>';
//分組命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
//http://www.atguigu.com
console.log(result.groups.text);
//尚矽谷
- 以前辦法
//宣告一個字串
let str = '<a href="http://www.atguigu.com">尚矽谷</a>';
//提取 url 與 『標籤文字』
const reg = /<a href="(.*)">(.*)<\/a>/;
// //執行
const result = reg.exec(str);
console.log(result);
//["<a href="http://www.atguigu.com">尚矽谷</a>", "http://www.atguigu.com", "尚矽谷", index: 0, input: "<a href="http://www.atguigu.com">尚矽谷</a>", groups: undefined]
console.log(result[1]);
//http://www.atguigu.com
console.log(result[2]);
// 尚矽谷
正則 正向斷言
//宣告字串
let str = 'JS5211314你知道麼555啦啦啦';
//正向斷言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result)
//["555", index: 13, input: "JS5211314你知道麼555啦啦啦", groups: undefined]
正則 反向斷言
//反向斷言
const reg = /(?<=麼)\d+/;
const result = reg.exec(str);
console.log(result);
//["555", index: 13, input: "JS5211314你知道麼555啦啦啦", groups: undefined]
. dotAll模式
-
dot . 元字元 除換行符以外的任意單個字元
-
正規表示式中點.匹配除回車外的任何單字元,標記『s』改變這種行為,允許行
終止符出現
let str = `
<ul>
<li>
<a>肖生克的救贖</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正傳</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//宣告正則
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//執行匹配
// const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//輸出結果
console.log(data);
ECMAScript10
Object.fromEntries
-
Object.entries和它相反
-
二維陣列
const result = Object.fromEntries([
['name','尚矽谷'],
['xueke', 'Java,大資料,前端,雲端計算']
]);
console.log(result)
//Object
//name: "尚矽谷"
//xueke: "Java,大資料,前端,雲端計算"
- Map
const m = new Map();
m.set('name','ATGUIGU');
const result = Object.fromEntries(m);
console.log(result)
//{name: "ATGUIGU"}
- Object.entries和它相反
const arr = Object.entries({
name: "尚矽谷"
})
console.log(arr);
//[Array(2)]
//0: (2) ["name", "尚矽谷"]
//length: 1
trimStart 和 trimEnd
- 清除左邊和右邊空白
<script>
// trim
let str = ' iloveyou ';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
</script>
Array.prototype.flat
-
flat 平
-
將多維陣列轉化為低位陣列
-
引數為深度 是一個數字
- 三維轉1維輸入2
- 預設值是1
const arr = [1,2,3,4,[5,6]];
console.log(arr.flat());
(6) [1, 2, 3, 4, 5, 6]
const arr = [1,2,3,4,[5,6,[7,8,9]]];
console.log(arr.flat());
(7) [1, 2, 3, 4, 5, 6, Array(3)]
const arr = [1,2,3,4,[5,6,[7,8,9]]];
console.log(arr.flat(2));
//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
flatMap
-
跟Map很像,只是把維度降低
-
兩個操作結合
const arr = [1,2,3,4];
const result = arr.map(item => item * 10);
console.log(result)
//(4) [10, 20, 30, 40]
----------------------------------------------------
const arr = [1,2,3,4];
const result = arr.map(item => [item * 10]);
console.log(result)
//0: [10]
//1: [20]
//2: [30]
//3: [40]
--------------------------------------------------------------
const arr = [1,2,3,4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);
//(4) [10, 20, 30, 40]
Symbol.prototype.description
- 獲取Symbol的描述字串
<script>
//建立 Symbol
let s = Symbol('尚矽谷');
console.log(s.description);
//尚矽谷
</script>
ECMAScript11
類的私有屬性
<script>
class Person{
//公有屬性
name;
//私有屬性
#age;
#weight;
//構造方法
constructor(name, age, weight){
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro(){
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
//例項化
const girl = new Person('曉紅', 18, '45kg');
// console.log(girl.name);
// console.log(girl.#age);
// console.log(girl.#weight);
//Private field '#age' must be declared in an enclosing class
girl.intro(); //曉紅 18 45
</script>
Promise.allSettled
- 接收promise一個陣列,返回的promise結果也是物件,不過返回的結果永遠是一個成功的狀態.而且成功的值是裡邊每一個promise狀態和結果
<script>
//宣告兩個promise物件
const p1 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('商品資料 - 1');
},1000)
});
const p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('商品資料 - 2');
// reject('出錯啦!');
},1000)
});
//呼叫 allsettled 方法
// const result = Promise.allSettled([p1, p2]);
// const res = Promise.all([p1, p2]);
console.log(res);
</script>
String.prototype.matchAll
- 用來得到正則批量匹配的結果
<script>
let str = `<ul>
<li>
<a>肖生克的救贖</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正傳</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//宣告正則
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
//呼叫方法
const result = str.matchAll(reg);
// for(let v of result){
// console.log(v);
// }
const arr = [...result];
console.log(arr);
</script>
.? 可選鏈操作符
<script>
// ?.
function main(config){
// const dbHost = config && config.db && config.db.host;
const dbHost = config?.db?.host;
console.log(dbHost);
}
main({
db: {
host:'192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username:'admin'
}
})
</script>
動態 import 匯入
<body>
<button id="btn">點選</button>
<script src="./js/app.js" type="module"></script>
</body>
export function hello(){
alert('Hello');
}
// import * as m1 from "./hello.js";
//獲取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
import('./hello.js').then(module => {
module.hello();
});
}
BigInt 大整形
- 不能直接與數值計算
- 不能使用浮點數計算
<script>
//大整形
let n = 521n;
console.log(n, typeof(n));
//521n "bigint"
//函式
let n = 123;
console.log(BigInt(n)); //123n
console.log(BigInt(1.2));
//大數值運算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);
console.log(max + 1);
console.log(max + 2);
console.log(BigInt(max))
console.log(BigInt(max) + BigInt(1))
console.log(BigInt(max) + BigInt(2))
</script>
絕對全域性物件globalThis
- 始終指向全域性物件
<script>
console.log(globalThis); //window
</script>
console.log(globalThis); //globakThis
相關文章
- JavaScript高階:JavaScript物件導向,JavaScript內建物件,JavaScript BOM,JavaScript封裝JavaScript物件封裝
- javaScript系列[06]-javaScript和thisJavaScript
- 【JavaScript學習】JavaScript物件建立JavaScript物件
- 【轉】eval()函式(javascript) - [javaScript]函式JavaScript
- JavaScript -"this"JavaScript
- javascript ??JavaScript
- This in JavaScriptJavaScript
- “This” is For JavaScriptJavaScript
- JavaScriptJavaScript
- javascript thisJavaScript
- javaScript系列[05]-javaScript和JSONJavaScriptJSON
- 44 道 JavaScript 難題(JavaScript Puzzlers!)JavaScript
- 【轉向JavaScript系列】AST in Modern JavaScriptJavaScriptAST
- javascript,還是javascript的問題JavaScript
- JavaScript 教程之JavaScript常用框架簡介JavaScript框架
- 《深入理解JavaScript》——2.3 JavaScript有用嗎JavaScript
- 【JavaScript】--JavaScript總結一覽無餘JavaScript
- 【HTML、JAVASCRIPT、CSS】3、Javascript基本概念HTMLJavaScriptCSS
- JavaScript EventJavaScript
- JavaScript BackdoorJavaScript
- JavaScript normalize()JavaScriptORM
- JavaScript setDate()JavaScript
- JavaScript setMinutes()JavaScript
- JavaScript getDate()JavaScript
- JavaScript setHours()JavaScript
- JavaScript setUTCMinutes()JavaScript
- JavaScript setUTCHours()JavaScript
- JavaScript setUTCFullYear()JavaScript
- JavaScript setUTCMonth()JavaScript
- JavaScript setUTCDate()JavaScript
- JavaScript getUTCMinutes()JavaScript
- JavaScript setMonth()JavaScript
- JavaScript getMonth()JavaScript
- JavaScript getMinutes()JavaScript
- JavaScript getYear()JavaScript
- JavaScript getHours()JavaScript
- JavaScript getUTCDate()JavaScript
- JavaScript getUTCMonth()JavaScript