載自:www.cnblogs.com/lihaoyang/p/6756956.html
開窗函數:在開窗函數出現之前存在著很多用 SQL 語句很難解決的問題,很多都要通過復雜的相關子查詢或者存儲過程來完成。為了解決這些問題,在 2003 年 ISO SQL 標準加入了開窗函數,開窗函數的使用使得這些經典的難題可以被輕松的解決。目前在 MSSQLServer、Oracle、DB2 等主流數據庫中都提供了對開窗函數的支持,不過非常遺憾的是 MYSQL 暫時還未對開窗函數給予支持。
開窗函數簡介:與聚合函數一樣,開窗函數也是對行集組進行聚合計算,但是它不像普通聚合函數那樣每組只返回一個值,開窗函數可以為每組返回多個值,因為開窗函數所執行聚合計
算的行集組是窗口。在 ISO SQL 規定了這樣的函數為開窗函數,在 Oracle 中則被稱為分析函數。
數據表(Oracle):T_Person 表保存了人員信息,FName 字段為人員姓名,FCity 字段為人員所在的城市名,FAge 字段為人員年齡,FSalary 字段為人員工資
CREATE TABLE T_Person (FName VARCHAR2(20),FCity VARCHAR2(20),FAge INT,FSalary INT)
向 T_Person 表中插入一些演示數據:
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tom','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tim','ChengDu',21,4000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jim','BeiJing',22,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Lily','London',21,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('John','NewYork',22,1000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YaoMing','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Swing','London',22,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Guo','NewYork',20,2800);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YuQian','BeiJing',24,8000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Ketty','London',25,8500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Kitty','ChengDu',25,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Merry','BeiJing',23,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Smith','ChengDu',30,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Bill','BeiJing',25,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jerry','NewYork',24,3300);
select * from t_person:
要計算所有人員的總數,我們可以執行下面的 SQL 語句:SELECT COUNT(*) FROM T_Person
除了這種較簡單的使用方式,有時需要從不在聚合函數中的行中訪問這些聚合計算的值。比如我們想查詢每個工資小于 5000 元的員工信息(城市以及年齡),并且在每行中都顯示所有工資小于 5000 元的員工個數:
select fname,
fcity,
fsalary,
(select count(*) from t_person where fsalary < 5000) 工資少于5000員工總數
from t_person
where fsalary < 5000
雖然使用子查詢能夠解決這個問題,但是子查詢的使用非常麻煩,使用開窗函數則可以大大簡化實現,下面的 SQL 語句展示了如果使用開窗函數來實現同樣的效果:
select fname, fcity, fsalary, count(*) over() 工資小于5000員工數
from t_person
where fsalary < 5000
可以看到與聚合函數不同的是,開窗函數在聚合函數后增加了一個 OVER 關鍵字。
開窗函數格式: 函數名(列) OVER(選項)
OVER 關鍵字表示把函數當成開窗函數而不是聚合函數。SQL 標準允許將所有聚合函數用做開窗函數,使用 OVER 關鍵字來區分這兩種用法。
在上邊的例子中,開窗函數 COUNT(*) OVER()對于查詢結果的每一行都返回所有符合條件的行的條數。OVER 關鍵字后的括號中還經常添加選項用以改變進行聚合運算的窗口范圍。如果 OVER 關鍵字后的括號中的選項為空,則開窗函數會對結果集中的所有行進行聚合運算。
PARTITION BY 子句:
開窗函數的 OVER 關鍵字后括號中的可以使用 PARTITION BY 子句來定義行的分區來供進行聚合計算。與 GROUP BY 子句不同,PARTITION BY 子句創建的分區是獨
立于結果集的,創建的分區只是供進行聚合計算的,而且不同的開窗函數所創建的分區也不互相影響。下面的 SQL 語句用于顯示每一個人員的信息以及所屬城市的人員數:
select fname,fcity,fage,fsalary,count(*) over(partition by fcity) 所在城市人數 from t_person
COUNT(*) OVER(PARTITION BY FCITY)表示對結果集按照FCITY進行分區,并且計算當前行所屬的組的聚合計算結果。比如對于FName等于 Tom的行,它所屬的城市是BeiJing,同
屬于BeiJing的人員一共有6個,所以對于這一列的顯示結果為6。
這就不需要先對fcity分組求和,然后再和t_person表連接查詢了,省事兒。
在同一個SELECT語句中可以同時使用多個開窗函數,而且這些開窗函數并不會相互干
擾。比如下面的SQL語句用于顯示每一個人員的信息、所屬城市的人員數以及同齡人的人數:
--顯示每一個人員的信息、所屬城市的人員數以及同齡人的人數:
select fname,
fcity,
fage,
fsalary,
count(*) over(partition by fcity) 所屬城市的人個數,
count(*) over(partition by fage) 同齡人個數
from t_person
ORDER BY子句:
開窗函數中可以在OVER關鍵字后的選項中使用ORDER BY子句來指定排序規則,而且有的開窗函數還要求必須指定排序規則。使用ORDER BY子句可以對結果集按
照指定的排序規則進行排序,并且在一個指定的范圍內進行聚合運算。ORDER BY子句的語法為:
ORDER BY 字段名 RANGE|ROWS BETWEEN 邊界規則1 AND 邊界規則2
RANGE表示按照值的范圍進行范圍的定義,而ROWS表示按照行的范圍進行范圍的定義;邊界規則的可取值見下表:
“RANGE|ROWS BETWEEN 邊界規則1 AND 邊界規則2”部分用來定位聚合計算范圍,這個子句又被稱為定位框架。
例子程序一:查詢從第一行到當前行的工資總和:
select fname,
fcity,
fage,
fsalary,
sum(fsalary) over(order by fsalary rows between unbounded preceding and current row) 到當前行工資求和
from t_person
這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW)”表示按照FSalary進行排序,然后計算從第
一行(UNBOUNDED PRECEDING)到當前行(CURRENT ROW)的和,這樣的計算結果就是按照
工資進行排序的工資值的累積和。
“RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”是開窗函數中最常使用的定位框架,為了簡化使用,如果使用的是這種定位框架,則可以省略定位框架聲明部分,
也就是說上邊的sql可以簡化成:
select fname,
fcity,
fage,
fsalary,
sum(fsalary) over(order by fsalary) 到當前行工資求和
from t_person
例子程序二:把例子程序一的row換成了range,是按照范圍進行定位的
select fname,
fcity,
fage,
fsalary,
sum(fsalary) over(order by fsalary range between unbounded preceding and current row) 到當前行工資求和
from t_person
區別:
這個SQL語句與例1中的SQL語句唯一不同的就是“ROWS”被替換成了“RANGE”?!癛OWS”
是按照行數進行范圍定位的,而“RANGE”則是按照值范圍進行定位的,這兩個不同的定位方式
主要用來處理并列排序的情況。比如 Lily、Swing、Bill這三個人的工資都是2000元,如果按照
“ROWS”進行范圍定位,則計算從第一條到當前行的累積和,而如果 如果按照 “RANGE”進行
范圍定位,則仍然計算從第一條到當前行的累積和,不過由于等于2000元的工資有三個人,所
以計算的累積和為從第一條到2000元工資的人員結,所以對 Lily、Swing、Bill這三個人進行開
窗函數聚合計算的時候得到的都是7000( “ 1000+2000+2000+2000 ”)。
下邊這的估計不常用:
例子程序三:
SELECT FName,
FSalary,
SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) 前二后二和
FROM T_Person;
這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 2
PRECEDING AND 2 FOLLOWING)”表示按照FSalary進行排序,然后計算從當前行前兩行(2
PRECEDING)到當前行后兩行(2 FOLLOWING)的工資和,注意對于第一條和第二條而言它們
的“前兩行”是不存在或者不完整的,因此計算的時候也是要按照前兩行是不存在或者不完整進
行計算,同樣對于最后兩行數據而言它們的“后兩行”也不存在或者不完整的,同樣要進行類似
的處理。
例子程序四:
SELECT FName, FSalary,
SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) 后面一到三之和
FROM T_Person;
這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 1
FOLLOWING AND 3 FOLLOWING)”表示按照FSalary進行排序,然后計算從當前行后一行(1
FOLLOWING)到后三行(3 FOLLOWING)的工資和。注意最后一行沒有后續行,其計算結果為
空值NULL而非0。
例子程序五:算工資排名
SELECT FName, FSalary,
COUNT(*) OVER(ORDER BY FSalary ROWS BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW)
FROM T_Person;
這里的開窗函數“COUNT(*) OVER(ORDER BY FSalary RANGE BETWEEN UNBOUNDED
PRECEDING AND CURRENT ROW)”表示按照FSalary進行排序,然后計算從第一行
(UNBOUNDED PRECEDING)到當前行(CURRENT ROW)的人員的個數,這個可以看作是計算
人員的工資水平排名。
不再用ROWNUM 了 省事了。這個over簡寫就會出錯。
例子程序6:結合max求到目前行的最大值
SELECT FName, FSalary,FAge,
MAX(FSalary) OVER(ORDER BY FAge) 此行之前最大值
FROM T_Person;
這里的開窗函數“MAX(FSalary) OVER(ORDER BY FAge)”是“MAX(FSalary)
OVER(ORDER BY FAge RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)”
的簡化寫法,它表示按照FSalary進行排序,然后計算從第一行(UNBOUNDED PRECEDING)
到當前行(CURRENT ROW)的人員的最大工資值。
例子程序6:over(partition by XX order by XX) partition by和order by 結合
員工信息+同齡人最高工資,按工資排序
SELECT FName, FSalary,FAge,
MAX(FSalary) OVER(PARTITION BY FAge order by fsalary) 同齡人最高工資
FROM T_Person;
PARTITION BY子句和ORDER BY 可以 共 同 使用,從 而 可以 實現 更 加復 雜 的 功能
==================================================================================
高級開窗函數/ 排名的實現ROW_NUMBER();rank() ,dense_rank()
除了可以在開窗函數中使用COUNT()、SUM()、MIN()、MAX()、AVG()等這些聚合函數,
還可以在開窗函數中使用一些高級的函數,有些函數同時被DB2和Oracle同時支持,比如
RANK()、DENSE_RANK()、ROW_NUMBER(),而有些函數只被Oracle支持,比如
RATIO_TO_REPORT()、NTILE()、LEAD()、LAG()、FIRST_VALUE()、LAST_VALUE()。
下面對這幾個函數進行詳細介紹。
RANK()和DENSE_RANK()函數都可以用于計算一行的排名,不過對于并列排名的處理方式
不同;ROW_NUMBER()函數計算一行在結果集中的行號,同樣可以將其當成排名函數。這三個
函數的功能存在一定的差異,舉例如下:工資從高到低排名:
SELECT FName, FSalary,FAge,
RANK() OVER(ORDER BY fsalary desc) f_RANK,
DENSE_RANK() OVER(ORDER BY fsalary desc) f_DENSE_RANK,
ROW_NUMBER() OVER(ORDER BY fsalary desc) f_ROW_NUMBER
FROM T_Person;
rank(),dense_rank()語法:
RANK()
dense_rank()
【語法】RANK ( ) OVER ( [query_partition_clause] order_by_clause )
dense_RANK ( ) OVER ( [query_partition_clause] order_by_clause )
【功能】聚合函數RANK 和 dense_rank 主要的功能是計算一組數值中的排序值。
【參數】dense_rank與rank()用法相當,
【區別】dence_rank在并列關系是,相關等級不會跳過。rank則跳過
rank()是跳躍排序,有兩個第二名時接下來就是第四名(同樣是在各個分組內)
dense_rank()l是連續排序,有兩個第二名時仍然跟著第三名。
row_number() 函數語法:
ROW_NUMBER()
【語法】ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2)
【功能】表示根據COL1分組,在分組內部根據 COL2排序,而這個值就表示每組內部排序后的順序編號(組內連續的唯一的)
row_number() 返回的主要是“行”的信息,并沒有排名
【參數】
【說明】Oracle分析函數
主要功能:用于取前幾名,或者最后幾名等
===================================================================
排序函數實際場景使用:計算排行榜,排名
微信活動,每天參與,有得分,活動結束后選出排名靠前的發獎。
每參與一次,就是一個訂單,表結構:
比如要查詢期號issue為20170410期的排行榜,按得分倒敘排序,得分一樣按訂單創建先后,算排行,sql需要這么寫:
select ROWNUM rank, t.*
from (select *
from t_zhcw_order
where issue='20170410'
order by integral desc, create_date asc) t
使用了開窗函數后就可以簡化:
select t.*,
row_number() over(order by t.integral desc, t.create_date asc) 排名
from t_zhcw_order t
where issue='20170410'
如果想只要排名范圍,可以在外邊再包一層,這也是高效分頁的一種方式:
1、在上一篇文章里給大家介紹oracle自動巡檢腳本生成html報告,這篇文章介紹linux服務巡檢腳本生成html報告。
2、腳本依然是簡單腳本語句的堆積,方便大家二次編輯使用。
3、項目已經上傳到我的github上
項目地址:https://github.com/domdanrtsey/oswatch.git
一定注意閱讀git上的README.md說明,避免部分信息無法正常顯示
1、使用root用戶執行
2、使用說明
1)、腳本中 ifconfig、mpstat、iostat命令有依賴,需要安裝相關依賴包
yum -y install bc sysstat net-tools
1
2)、執行完巡檢之后,將在腳本所在的路徑下生成html巡檢結果報告,如下
192.168.31.102os_linux_summary.html
3)、巡檢項信息如下(其他統計項可根據實際需要自行添加)
1)、系統基本信息
2)、cpu信息
3)、ip網絡信息
4)、cpu使用率
5)、連接數信息
6)、系統限制信息
7)、內存使用信息
8)、磁盤使用信息
9)、網絡流量情況/系統資源變化
10)、cpu消耗情況前10排行
11)、cpu消耗按內存情況前10排行
12)、磁盤io情況
13)、系統定時任務列表
14)、系統定時任務腳本內容
單理解:
ECMAScript是一個標準,
JavaScript是一個實現 。
ECMAScript是一種由Ecma國際(前身為歐洲計算機制造商協會,英文名稱是European Computer Manufacturers Association)通過ECMA-262標準化的腳本程序設計語言。這種語言在萬維網上應用廣泛,它往往被稱為JavaScript或JScript,所以它可以理解為是JavaScript的一個標準,但實際上后兩者是ECMA-262標準的實現和擴展。
JavaScript一種直譯式腳本語言,是一種動態類型、弱類型、基于原型的語言,內置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于客戶端的腳本語言,最早是在HTML(標準通用標記語言下的一個應用)網頁上使用,用來給HTML網頁增加動態功能。
JavaScript是通用的跨平臺腳本語言,遵守ECMA-262標準(ES標準),換句話說就是ECMAScript的方言。為了取得技術優勢,微軟推出了JScript,CEnvi推出ScriptEase,與JavaScript同樣可在瀏覽器上運行。為了統一規格,因為JavaScript兼容于ECMA標準,因此也稱為ECMAScript。
JavasSript商標屬于Oracle公司,因為Sun公司被Oracle收購。JavaScript早年被Sun公司注冊,代表JavaScript這門語言。但是最早發明JavaScript是網景公司。在1995年時,由Netscape公司的Brendan Eich,在網景導航者瀏覽器上首次設計實現而成。因為Netscape與Sun合作,Netscape管理層希望它外觀看起來像Java,因此取名為JavaScript。但實際上它的語法風格與Self及Scheme較為接近。
ES6經過持續幾年的磨礪,它已成為 JS 有史以來最實質的升級,特性涵蓋范圍甚廣, 小到受歡迎的語法糖,例如箭頭函數(arrow functions)和簡單的字符串插值(string interpolation),大到燒腦的新概念,例如代理(proxies)和生成器(generators);它將徹底改變程序員們編寫JS代碼的方式。
ES6兼容性列表:http://kangax.github.io/compat-table/es6/
ES6兼容性列表
let關鍵字
let a;
let b, c, d;
let e=1;
let f=1, g="hello";
const定義常量
const MAX_AGE=100;
變量的解構賦值
//數組的解構
const TEST01=[1,2,3,4];
let [a, b, c, d]=TEST01;
//對象的解構
const TEST02={name:"zhangsan", age:10,say:function(){}};
let {name, age, say}=TEST02;
模板字符串
//字符串賦值方式有:"",''
//ES6新增:``
let name="張三";
let str=`你好,${name}`;
簡化對象寫法
let name="張三";
let say=function(){};
//簡化寫法
let zhangsan={
name,
say
};
//等效于
let zhangsan={
name: name,
say: say
};
//方法聲明簡化
let test={
say(){
console.log("你好");
}
};
//等效于
let test={
say: function(){
console.log("你好");
}
};
箭頭函數
//聲明方式:=>定義函數
let add=(a, b)=>{
return a+b;
}
函數參數默認值
//ES6允許函數參數賦值默認值
function add(a,b=10){
return a+b;
}
rest參數:可變參數
// ...表示
function(...args){
console.log(args);//數組
}
擴展運算符
//[...]擴展運算符:將數組轉換為逗號分割的參數序列。
let a=[1,2,3];
function say(){
console.log(arguments);
}
say(...a);//實參位置,相當于:say(1,2,3);
Symbol原始數據類型
let s=Symbol();
let s1=Symbol("你好");
let s2=Symbol("你好");
//s1===s2:false
let s3=Symbol.for("你好");
let s4=Symbol.for("你好");
//s3===s4:true
//使用
let person={
name:"張三",
say:function(){
}
};
let methods={
say:Symbol("say")
};
person[methods.say]=function(){
};
//這樣就可以預防新增加方法影響原有的方法。
迭代器
ES6: for...of循環進行遍歷。
原生具備iterator接口的數據:Array,Arguments,Set,Map,String,TypedArray,NodeList。
iterator接口:指的是對象內部的一個屬性Symbol.iterator。
let nums=[1,2,3];
// for..of:n為鍵值。
// for..in:n為鍵名稱。
for(let n of nums){
console.log(n);
}
//迭代器
let iterator=nums[Symbol.iterator];
// 自定義迭代器事例
let person={
name:"張三",
works:["A","B"],
[Symbol.iterator](){
//索引
let index=0;
return {
//包含next函數
next:()=> {
//返回值:value和done
if(index < this.works.length){
let result={value:this.works[index],done:false};
index++;
return result;
}else{
return {value:undefined,done:true};
}
}
};
}
};
for(let w of person){
console.log(w);
}
生成器
//1.基礎用法
function * gen(){
console.log("hello");
}
let it=gen();
//真正執行,輸出hello
it.next();
//2.yield關鍵字:代碼片段
function * gen(){
console.log("hello-A");
yield "A";
console.log("hello-B");
yield "B";
}
//返回迭代器對象
let it=gen();
it.next();//hello-A
it.next();//hello-B
for(let f of gen()){
console.log(f);//輸出的是yield內容
}
//3.生成器參數
function * gen(arg){
console.log(arg);
let one=yield 1;
console.log(one);
let two=yield 1;
console.log(two);
}
let it=gen("A");
it.next("B");//A
it.next("C");//B
it.next();//C
Promise諾言
//resolve成功->then第一個函數
//rejects失敗->then第二個函數或catch
const p=new Promise(function(resolve,reject){
//resolve(data);
//reject(data)
});
p.then(function(data){
//成功
},function(data){
//失敗
});
p.then(function(data){
//成功
}).catch(function(data){
//失敗
});
//Promise.prototype.then:
//默認返回結果是Promise
//成功回調結果,則為返回的數據結果。
//拋出錯誤,失敗的Promise
//可以鏈式調用。
Set數據結構
類似于數組,但是成員的值都是唯一的,并實現了iterator接口??梢允褂脭U展運算符和for-of進行遍歷。
let s=new Set();
let s1=new Set([1,2]);
//屬性和方法
s1.size;//元素個數
s1.add(3);//添加新元素
s1.delete(3);//刪除元素
s1.has(3);//是否存在
s1.clear();//清空
for(let a of s1){}//for-of操作。
let arr1=[...s1];//擴展運算符:1,2數組
//用途:去重
let arr=[1,2,3,2];
let arr2=[...new Set(arr)];
Map數據結構
類似于對象,鍵值對集合。但是鍵的類型不限于字符串,各種類型都可以當作鍵。
Map也事項了iterator接口,也可以使用擴展運算符和for-of進行遍歷。
let m=new Map();
let m=new Map([["birth","201212"],["firstName","張"]]);
m.set("name","張三");//添加元素
m.size;//數據量
m.delete("name");//刪除
m.get("name");//獲取
m.clear();//清空
for(let a of m){
//a類型為數組:[key,value]
}
class類
Es6引入了class的概念,作為對象的模板,通過class關鍵字定義。
可以看作是一個語法糖,絕大部分功能Es5都能實現,但是class寫法讓對象原型的寫法更清晰,更像面向對象的語法。
class Person {
//構造方法,名字固定不能修改
constructor(name, age) {
this.name=name;
this.age=age;
}
//方法結構必須方法名稱加括號,不能使用ES5方式
say() {
console.log(`你好,${this.name}!`);
}
//靜態屬性方法:關鍵字static
static maxAge=200;
static getMaxAge() {
return maxAge;
}
}
//繼承:extends
class Worker extends Person {
constructor(name, age, workAge) {
super(name, age);
this.workAge=workAge;
}
work() {
console.log("工作");
}
//方法重寫
say() {
console.log(`我是員工${this.name}!`);
}
}
//get和set
class Dog {
//get方法
get name() {
console.log("get name調用");
return this.name;
}
set name(name) {
console.log("set name調用");
this.name=name;
}
}
let dog=new Dog();
dog.name; //get使用方式
dog.name="doudou"; //set方式
數值的擴展-Number
對象方法地擴展-Object
模塊化
模塊化:大文件拆成小文件,然后將小文件合并起來。
好處:
防止命名沖突。代碼復用。高維護性。
ES6之前地模塊化規范有:
CommonJS:NodeJS,BrowserifyAMD:requireJSCMD:seaJS
ES6模塊化規范:
//分別暴露
export let name="zhangsan";
export function say(){}
//統一暴露
let name="zhangsan";
function say(){}
export {
name,
say
};
//默認暴露
let name="zhangsan";
function say(){}
export default {
name,
say
};
//通用導入方式
import * as P from "test.js";
//解構賦值形式
import {name, say as hello} from "test.js";
//默認暴露的引入方式,2種方式等價
import {default as P} from "test.js";
import P from "test.js";
<script type="module">
import * as P from "test.js";
//一通操作
</script>
<script src="./app.js" type="module"></script>
//app.js文件內部進行引入等一通操作
import * as P from "test.js";
//一通操作
ES7(ES2016)新特性
const a=[1, 2];
a.includes(1);
let a=2 ** 10;//2的10次方=1024,等價:Math.pow(2,10);
ES8(ES2017)新特性
async和await讓異步代碼看起來跟同步代碼一樣。
//async函數
async function fn() {
//返回結果不是一個promise類型的對象,返回結果就會是成功的promise。
//return "hello";
//拋出錯誤,返回結果是一個失敗的promise
//throw new Error("hello");
//返回結果是一個promise對象。
}
let result=fn();
result.then((value)=> {
console.log("成功");
}).catch((error)=> {
console.log("失敗");
});
await必須放到async函數中;
await右側的表達式一般為promise對象。
await返回promise成功的值。
await的promise失敗了,就會拋出異常,需要通過try-catch捕獲處理。
//創建promist
function getUser() {
return new Promise((resolve, reject)=> {
resolve("user info");
});
}
//await必須要在async函數中
async function main() {
try {
//resolve成功數據
let userInfo=await getUser();
console.log(userInfo);
} catch (error) {
//reject失敗數據
console.error(error);
}
}
Object.values和Object.entries:
let a={name:"dd",age:12};
//對象所有的鍵
Object.keys(a);
//對象所有的值
Object.values(a);
//返回每個元素的鍵值數組[key,value]
Object.entries(a);
//屬性描述對象
Object.getOwnPropertyDescriptor(a);
ES9(ES2018)新特性
function test({a, b, ...others}){
console.log(a);
console.log(b);
console.log(others);
}
test({
a:1,
b:2,
c:3,
d:4
});
//輸出:1,2,{c:3,d:4}
//對象擴展
let a={name:"張三"};
let b={age:12};
let c={...a,...b};//{name:'張三',age:12}
//以前
let str="<a href='http://nomax.cn'>諾碼信科技</a>";
let reg=/<a href='(.*)'>(.*)<\/a>/;
let result=reg.exec(str);
console.log(result[1]); //http://nomax.cn
console.log(result[2]); //諾碼信科技
//現在:?<url>
let str="<a href='http://nomax.cn'>諾碼信科技</a>";
let reg=/<a href='(?<url>.*)'>(?<text>.*)<\/a>/;
let result=reg.exec(str);
console.log(result.groups.url); //http://nomax.cn
console.log(result.groups.text); //諾碼信科技
ES10(ES2019)新特性
//二維數組
let re=Object.fromEntries([
['name':'張三'],
['age', 20]
]);
let arr=[1,2,[3,4]];
arr.flat();//1,2,3,4
//arr.flat(deep);--deep代表深度,默認1,如果三維數組展開,就需要傳遞2.
//flatMap可以看作是flat和map2個操作的結合。
let arr2=[1,2,3];
//以下2中方式等價
let arr3=arr2.map(item=>[item*10]);
let arr4=arr3.flat();
//flatMap方式。
let arr4=arr2.flatMap(item=>[item*10]);
let s=Symbol("hello");
s.description;//返回hello
ES11(ES2020)新特性
class Persion {
//公有屬性
name;
//私有屬性
#age;
constructor(name, age) {
this.name=name;
this.#age=age;
}
}
const p1=new Promise((resolve, reject)=> {
resolve("data1");
});
const p2=new Promise((resolve, reject)=> {
reject("error2");
});
//返回成功的promise,內部結果數組對每個記錄狀態。
let re=Promise.allSettled([p1, p2]);
//有一個失敗,就返回失敗的Promise
let re2=Promise.all([p1, p2]);
function main(config) {
//原先的獲取方式
//let host=config && config.db && config.db.host;
//現在-?.
let host=config?.db?.host;
}
main({
db: {
host: "127.0.0.1",
port: "3306",
},
});
function btnClick() {
//通過import函數動態導入模塊,返回結果為promise,參數為導入模塊
import("./test01").then((module)=> {
module.sayHell("d");
});
}
let n=222n;
typeof(n);//bigint
//普通值轉biginit
BitInit(122);
//主要用于大整數的運算
console.log(globalThis);
學無止境!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。