载自: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_personCOUNT(*) 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_personORDER BY子句:
开窗函数中可以在OVER关键字后的选项中使用ORDER BY子句来指定排序规则,而且有的开窗函数还要求必须指定排序规则。使用ORDER BY子句可以对结果集按
照指定的排序规则进行排序,并且在一个指定的范围内进行聚合运算。ORDER BY子句的语法为:
ORDER BY 字段名 RANGE|ROWS BETWEEN 边界规则1 AND 边界规则2RANGE表示按照值的范围进行范围的定义,而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”。“ROWS”
是按照行数进行范围定位的,而“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
12)、执行完巡检之后,将在脚本所在的路径下生成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();//CPromise诺言
//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接口。可以使用扩展运算符和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;//返回helloES11(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小时内与您取得联系。