Es6-Es11

1.let
  1.不能重复声明
  2.块级别作用域 全局 函数 eval
  3.不存在变量提升
  4.不影响作用域链
  5.用途举例:a.点击5个div
2.const
  1.大写
  2.必须赋值
  3.不能修改
  4.块级作用域
  5.对于引用类型的修改 不算修改
3.let {} = zhao //结构化赋值
4.let b="hello",str = `abcd5${b}`;//模板字符串
5.对象简化
 1   let name = "zhagnsan",say = funtion(){console.log("I am zhangsan")}; 2   let person = {name,say,play(){console.log("I can play")}} 
6.箭头函数
  a.()=>{}
  b.this 静态只和定义时候的环境有关
    1.哪怕fn.call调用也不行
  c.不能作为构造函数来使用
  d.没有arguments 如果使用会提示 undefiend
  e.简写
    0.省略小括号,有且只有一个参数
    1.省略花括号,n=>n*n(有切仅有一个参数,仅有一句返回且不能有 return)
  f.应用场景:
    1.点击div 2秒后变色,普通函数 setTimeout 里面的函数 指向 window 如果是箭头函数 指向div 自己
    2.arr.filter(item=>item % 2 == 0);返回数组里面的偶数
7.参数默认值
  1.function sum(a,b,c=3){return a+b+c} sum(1,2)
  2.与结构赋值相结合
    function person({name,age:25}){console.log(name)} let p1={name:"zs"}
    person(p1);
  3. ...rest 代替 arguments 结果是数组 必须放最后 function(a,b,...args)
  4.扩展运算符 和 rest 相反的样子
    a.arr = ["a","b"] , function a({console.log(arguments)}) a(arr) 此时 arguments 一个参数 a(...arr) 此时 arguments 两个参数
    b.应用如下:
      1.a1 = ["a","b"] , a2 = ["c","d"],a2 = [...a1,...a2] 类似 a3 = a1.concat(a2)
      2.数组的克隆 避免地址传递
      3.伪数组转为真正的数组
8.symbol
  1.唯一 let s2 = Symbol("dog"),s3 = Symbol("dog") //在这里 s2 != s3
  2.let s2 = Symbol.for("dog"),s3 = Symbol.for("dog")// 在这里 s2 === s3
  3.let method={up:Symbol(),down:Symbol()},let bolloon = {up,down} bollon[method.up]=function(){} 不覆盖
  4.let person = {[Symbol("say")]:function(){console.log("I can say")}} //Symbol("say")必须有[]
  5.class Person{static [Symbol.hasInstance](para){console.log("I am checked")}} console.log({} instanceof Person) 检测对象时候触发 para是对象{}
  6.arr2[Symbol.isConcatSpreadable] = fasle;//arr1.concat(arr2) arr2 不展开 //[1,2,3,arr2]

 //关于获取Symbol 的文本 Symbol.prototype.description let s0 = Symbol("up"); console.log(s0.description) let s1 = Symbol.for("down"); console.log(s1.description)

9.生成器函数
  1.function *gen(){
    let res1 = yield fn1();
    let res2 = yield fn2(res1);
  }
  2.iterator = gen();
  3.iterator.next() 执行
  4.iterator.next("a") 如果第二次执行传参 是第一个 yield 的返回值 也就是说 res1的值是"a"
  5.fn2(res1) fn2函数的传参不受影响 正常的参数 和 next 传的参数是yield的返回结果

  6.详细理解

    1.第一次next执行到 yield fn1() 包含这句话 同时把 fn1() 的结果返回出去 作为 {value:"",state:false} 中 value 的结果 ,但是  fn1() 这个返回结果 并不会给 let res1 =  它只能等外部 

      1.下一次  外部 next(para) 传参调用后 才会赋值 我给你个value 你给我个参数作为 yield 的 赋值的返回结果 有来有回 来而不往非礼也

    2.常见应用

      1.生成文章的id  function* gen(){let id =0; while(true){yield id;id++}} let id = gen() let artical = {artid:id.next().value,title:"zs"}  {artid:id.next().value,title:"zs"} 

        1.生成器函数写死循环也没有关系

 10.promise

let ai = new Promise ((reslove,reject) => {
    fs.readFile("./wx.txt",function(error,data) {
        if (error) reject(error);
        else reslove(data.toString());
    })
})

ai.then((data)=>{
    console.log(data)
},(error)=>{
    console.log(error)
})

//example 2
 
let ai = new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open("GET","https://api.apiopen.top/api/getTime");
    xhr.send();
    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(xhr.response);
            } else {
                reject(xhr.status);
            }
        }
    }
})

let res = ai.then((data) => {
    console.log(data)
    //then 的返回值 res 有:
        //1.非 promise 结果为promise成功 如:return 1111 //state:fulfilled result:1111
        //2.promise 结果 结果为 promise 的结果
        //3.抛出错误 throw 1111 结果为 promise 失败 //state:rejected result:1111
}, (error) => {
    console.error(error)
})
 

//Promise 中的 allSetted race all 的不同用法
let p1 = new Promise((resove,reject)=>{
    setTimeout(()=>{
        resove("用户zs登录成功")
        // reject("用户zs登录失败")
    },100)
})
let p2 = new Promise((resove,reject)=>{
    setTimeout(()=>{
        resove("用户ls登录成功")
        // reject("用户ls登录失败")
    },1000)
});
//必须p1和p2都resolve是成功 这个res才是成功的 走 then 的第一个回调 v 是一个数组 里面是所有的 p 的结果
//有任何一个失败 都会走 then 的第二个回调
//如果在一直在等待 promise 的执行结果 状态就是 pending
//只要 [p1,p2] 中 发现有一个失败的 类似 && res直接结果就是 result 就是失败的那个结果 状态也是 reject 反之,如果都成功 状态是 fulfilled result 是个数组
let res =  Promise.all([p1,p2]);

res.then((v)=>{
    console.log(res)
    console.log("ssssss")
    console.log(v)
    console.log("-------------------------------")
},(v)=>{
    console.log(res)
    console.log("ffffff")
    console.log(v)
    console.log("-------------------------------")
})

 //相同的代码省略掉了 这里 p1 快速 失败 p2 慢些成功 //不管成功失败 只要有一个执行出结果 就是 res最后的值 也就是说 res 只有一个结果 let res = Promise.race([p1,p2]); 

 //只要全部执行完毕 不管成功失败 对于res状态来说 都是成功的 fullfilled 结果呢永远是所有p的数组 并且是一个promise数组 //race 和 all 返回的是 普通的值 不是 promsie let res = Promise.allSettled([p1,p2]) 

 10.Set

//基本方法属性
let s1 = new Set(["a","b","c"])
console.log(s1.size) // 3
s1.add("d")
s1.delete("a")
s1.has("b")
s1.clear();
//应用

//数组去重复
let a1 = [1,1,3,3,0]
let s2 = new Set(a1)
a1 = [...s2]
console.log(a1) // [ 1, 3, 0 ] 

//求数组交集
let j1 = [1,2,3,2,3,4,5,3,6];
let j2 = [2,3,2,3]
let jres = [...new Set(j1)].filter(item => new Set(j2).has(item));
console.log(jres) // [ 2, 3 ]

//求并集
let b1 = [1,3,2,3,2];
let b2 = [2,3,4,5];
let bres = [...new Set([...b1,...b2])]
console.log(bres) //[ 1, 3, 2, 4, 5 ]

//求差集
let c1 = [1,2,3,2,3,3,1];
let c2 = [3,4,5,6]
let cres = [...new Set(c1)].filter(item => !(new Set(c2).has(item)));
console.log(cres) // [ 1, 2 ]

11.Map

//基本方法属性
let m1 = new Map()
console.log(m1.size)
m1.set("name","zs");
m1.set("age","30");
m1.get("name");
console.log(m1) //{ 'name' => 'zs', 'age' => '30' }
for (let v of m1){
    console.log(v); //[ 'name', 'zs' ] // [ 'age', '30' ]
}
m1.clear()

 12.Es5和Es6类Class

function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
}
//静态属性和方法
Phone.country = "china"
Phone.love = function () {
    console.log("I love china");
}

Phone.prototype.call = function () {
    console.log("I can call phone")
}

let hw = new Phone("huawei", 999)
hw.call() //I can call phone
console.log(hw) //Phone { brand: 'huawei', price: 999 }
console.log(Phone.country); // china
Phone.love() //I love china

//Es5对象的继承
function SmartPhone(brand, price, age) {
    Phone.call(this, brand, price);
    this.age = age;
}
SmartPhone.prototype = new Phone();
SmartPhone.prototype.constructor = SmartPhone;

SmartPhone.prototype.play = function () {
    console.log("I can play game");
}

let sp = new SmartPhone("chuizi",99.99,1983);
console.log(sp)

//About Es6
class Phone2 {
    constructor(brand, price) {
        this.brand = brand;
        this.price = price;
    }
    //静态属性和方法
    static country = "japan"
    static love() {
        console.log("I love japan");
    }
    set name(val){
        console.log("set attribute name " + val)
    }
    get name(){
        console.log("access attribute name")
    }
    call() {
        console.log("I can call phone")
    }
}

class SmartPhone2 extends Phone2{
    constructor(brand, price, age){
        super(brand,price);
        this.age = age;
    }
    play(){
        console.log("I can play game");
    }
}

let hw2 = new Phone2("Sony", 888)
hw2.call() //I can call phone
console.log(hw2) //Phone2 { brand: 'xiaomi', price: 888 }
console.log(Phone2.country);//japan
Phone2.love();//I love japan
hw2.name; //access attribute name
hw2.name = "zs"; //set attribute name zs

let sp2 = new SmartPhone2("epson","1.99",1968);
console.log(sp2);
 

//关于类的私有属性
//Es5 中用闭包的模式来实现私有属性
function Person(name,age){
    var age;
    this.name = name;
    this.sayName = function(){
        console.log("my name is "+ this.name)
    }
    this.setAge = function(a){
        age = a;
    }
    this.getAge = function(){
        //这里不能用 this.age
        console.log("my age is " + age);
    }
}
let zs = new Person("zs",99);
//只能通过提供的内部方法访问
zs.getAge(); //99
zs.setAge(18);
zs.getAge(); //18
//此时zs.age 是 undefined
console.log(zs.name,zs.age)
console.log("---------------------------")

//Es6中私有属性的实现 通过#来实现
class Person1{
    #age;
    name;
    constructor(name,age){
        this.name = name;
        this.#age = age;
    }
    getAge(){
        console.log("my age is " + this.#age);
    }
    setAge(age){
        this.#age = age;
    }
}
let p0 = new Person1("ls",88);

// 如果访问 p0.#age 会出现错误提示:Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
// 但 p0["#age"] 没问题 提示 undefined
console.log(p0,p0.name,p0["#age"]);//{} ls undefined
p0.getAge();//88
p0.setAge(77);
p0.getAge()//77

13.数值方法的扩展 Number 和 Math

console.log(Number.EPSILON) // 2.220446049250313e-16
console.log(0.1 === 0.3 - 0.2)  //false
console.log(equal(0.1 , 0.3 - 0.2)) //true
function equal(a,b){
    if(a - b <= Number.EPSILON){
        return true
    }else{
        return false;
    }
}
console.log(Number.isFinite(100/0)) //false;
console.log(Number.isFinite(Infinity)) //false
console.log(Number.isFinite(100.10)) //true
console.log(Number.isNaN(Infinity)) //false
console.log(Number.isNaN(100/0)) //false
console.log(Number.parseInt("5265.36love")) //5265
console.log(Number.parseFloat("5265.36love")) //5265.36
console.log(Number.isInteger(5265.36)) //false
console.log(Number.isInteger("5265")) //false
console.log(Math.trunc(3.5)) //3
console.log(Math.sign(0)) //返回符号 正数 1  零 0 负数 -1
//about BigInt 之所以引入这个概念是因为 超过最大安全整数的数字 就不安全了
console.log(Number.MAX_SAFE_INTEGER) //9007199254740991
let n0 = Number.MAX_SAFE_INTEGER;
//大于这个最大安全整数后再加会出问题
console.log(n0 + 1) //9007199254740992
console.log(n0 + 2) //9007199254740992
//也可以用 isSafeInteger 函数来验证
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)) //true
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)) //false
console.log("-----------------------")
//数字后面加n就是大整数 但是浮点数后面加n不行
let n1 = 123n;
console.log(n1,typeof n1); //123n 'bigint'
//把n0 转化为 bigInt 就不会出错了
let n2 = BigInt(n0);
console.log(n2,typeof n2) //9007199254740991n 'bigint'
console.log(n2 + BigInt(1)) //9007199254740992n
console.log(n2 + BigInt(2)) //9007199254740993n
//BigInt 类型和普通的类型无法直接相加 需要把普通的整数转化为 BigInt 类型才能相加
console.log(n2 + 1) //报错: test.js:51 Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

14.进制相关

 //各种进制 let n2 = 0b1010; let n8 = 0o771; let n10 = 998; let n16 = 0xff; 

15.Object 对象的方法补充

//对象方法的扩展
console.log(NaN === NaN) //false
console.log(Object.is(NaN, NaN)) //true //全等 相当于 === 可判断 NaN 是否等于 NaN
//对象的合并
let con1 = {
    host: "192.168.0.11",
    port: 80,
    password: "admin"
}
let con2 = {
    password: "nopwd",
    charset: "utf-8"
}
console.log(Object.assign(con1, con2)) //{ host: '192.168.0.11', port: 80, password: 'nopwd', charset: 'utf-8' }
相当于 {...
con1, ...con2} 都展开 后面会覆盖前面
console.log(con1) //{ host: '192.168.0.11', port: 80, password: 'nopwd', charset: 'utf-8' }
//设置对象的原型对象
let o1 = { name: "songjiang" }
let o2 = { nativePlace: "liangshan" }
Object.setPrototypeOf(o1, o2); //o1的 prototype 是 o2 o2的 prototype 是 Object
//对象方法的扩展
let oStu = {
    name:"zs",
    hoobies:["smoking","drinking","perm"],
    friends:["zs","ls","ww"]
};
console.log(Object.keys(oStu));
console.log(Object.values(oStu));
//获取对象的 entry 是一个 数组 套数组 [0:[k,v]]
let mapElements = Object.entries(oStu);
console.log(mapElements)
//entries 正好可以用户 new Map的参数 [0:[k,v],1:[k1,v1]]
let map1 = new Map(mapElements);
console.log(map1);

//获得对象的每个属性的定义描述符号
console.log(Object.getOwnPropertyDescriptors(oStu));

//定义一个prototype 为 null的对象 和 {} 效果不一样 cObj.__proto__ 会是 Object,但 Object.setPrototypeOf(cObj,null) 的 cObj.__proto__ 会是 undefined
//和 Object.setPrototypeOf(cObj,{}) 功能类似

let cObj = Object.create({},{
    name:{
        value:"zs",
        writable:true,
        enumerable:false,
        cofigurable:true
    },
    age:{
        value:26,
        writable:false,
        enumerable:true,
        configurable:false
    }
})

//cObj 的 age 属性是不可以删除的 因为 age的 configurable 为 false,并且不可以更改,因为writable 为false
//cObj 的 name 属性 不可以通过 for in 枚举出来 因为 enumerable 为 false
cObj.name = "武松";
cObj.age = 99;
console.log(cObj)
for (let k in cObj){
    console.log(k +"-->" + cObj[k])
}

//对象的 Object.fromEntries
//Object.entries 把对象转成一个二维数组 而 fromEntries 正好相反 把二维数组转成对象
let stu = {
    name:"zs",
    age:18
}
let res = Object.entries(stu);
console.log(res)
//把二维数组转成对象
let stu2 = Object.fromEntries(res);
console.log(stu2)
//Map 可以 直接把二维数组转换成Map
let map1 = new Map(res);
console.log(map1)
//fromEntries 可以直接把 Map 转为对象
map1.set("school","红旗小学");
let stu3 = Object.fromEntries(map1);
console.log(stu3);
//可选链操作符 如果有就显示 如果没有 就是 undefined 类似 option && option.user && option.user.name
function config(option){
    let user = option?.user?.name;
    let pwd = option?.user?.pwd;
    let cache = option?.user?.cache;
    console.log(user,pwd,cache);
}
let option = {
    host:"192.168.0.1",
    port:8080,
    user:{
        name:"zs",
        pwd:"1111"
    }
}
config(option);//zs 1111 undefined
//??怎么用呢
let a = obj.name || "zs" 只有当 obj.name 为 null 或 undefined a="zs" 和 || 语法是有区别的

16.模块化开发

//模块化
//Es6之前由社区开发的模块有
    //1.CommonJS => NodeJS Browserify
    //2.AMD => requireJS
    //3.CMD => SeaJS
//Es6 模块化语法主要有 export 和 import 两个命令来完成
//export
    //1.分别暴露 t1.js
    export let school = "红星小学";
    export function study(){
        console.log("我们要好好学习")
    }
    //2.统一暴露
    let school = "红星小学";
    function study(){
        console.log("我们要好好学习")
    }
    export{school,study}

    //3.默认暴露
    export default{
        school : "红星小学",
        study(){
            console.log("我们要好好学习")
        }
    }
  //4.export与export default混合用法  
//demo.js
var num = 123;
export var age = 18;
export var name = 'tom';
export default num;

//index.js
import AA, {age,name} from './demo.js';
console.log(AA,age,name);
// AA就是demo.js中默认导出的num AA 可以写在前面 但是不可以写在后面 比 import {age,name},AA from './demo.js'; 报错
// default 仅仅是一个特殊的导出变量而已 {default:default}
//在一个模块中export default 只能使用一次,export可以多次

--------------------------------------------------------------------
  注意:关于 export default 
var num = 123;
export default num;
//错误写法
export default var num = 123;
//因为export default num 的意思是把变量num的值赋值给变量default;
//所以不能写成export default var num = 123;

引用时候

import num from 'demo.js';

//或者
import aa from 'demo.js';
//注意不能加 {}
 
//在页面引用模块
    <script type="module">
        //通用导入方式
         import * as mm from "./t.js";
         //结构赋值导入方式 , 适合于非默认导出的引入
         import {school ,study } from "./t.js";
         import {school as sl,study as sy} from "./t.js";
         import {default as mm} from "./t.js"; //对象和通用导入方式差不多
        //简便导入模式 只适用于 默认暴露
        import mm from "./t.js"; //结果如同:import {default as mm} from "./t.js"; //对象和通用导入方式差不多
         console.log(mm);
    </script> 
 
  总结:不管怎么引入 引入的都是对象 哪怕是单独暴露 也是对象 要么进行结构化赋值 要么引入对象 去引用 对于起了别名的 其实本质上 还是 模块化赋值了 key不动 动了 value
      只是 默认 key 和 value 一样
      关于结构化赋值 对于 其他的属性 必须对应 暴露时候的 key 但是对于 default 不必 拿什么东西接住都可以
 
    <script src="./app.js" type="module">
        //app.js 作入口 在页面中引入下面代码
            import m1 from "./t.js";
            import * as m2 from "./tt.js";
            console.log(m1, m2)
    </script>

//模块的动态 import 比如 当点击的时候导入模块 不点击的话就不导入
function dynamicImport(){
    const btn = document.querySelector("#btn");
    btn.onclick = function(){
        import("./es6Mod.js").then((module)=>{
            console.log(module);
        })
    }
}
dynamicImport();

 17.array 数组的 一些特性

 array0 = ["a", "b"] console.log(array0.includes("a"))// true console.log(array0.indexOf("a"))// 0 

//Array.flat Array.flatMap
let arr1 = [1,2,3,[4,5,[6,7,8]]]
//[6,7,8]不做扁平化处理
console.log(arr1.flat(1))
//扁平化处理深度为2 变成 一维数组
console.log(arr1.flat(2))
arr1 = [1,2,3]
 let arr2 = arr1.map(function(v,k,ori){
    return [v*2,k];
})
//返回数组后 新的数组就是一个二维数组
console.log(arr2)
arr2 = arr1.flatMap(function(v,k,ori){
    return [v*2,k];
},1)
console.log(arr2)

18.async 函数 await 

async function ac() {
    //返回非promise的任何数据 都会返回一个 状态为 fulfilled 的promise 对象,默认返回一个 undefined 状态为 fullfilled 的 promise 对象
    //如果返回 promise 函数的结果就是 这个promise 对象
    //如果抛出错误 或者发生错误 结果为 状态为 rejected 值 为抛出的错误  或者发生的错误
    fewfwefwff
}
console.log(ac())
async function ac() {
    //await 必须写在 async 函数里面
    //await 右侧的表达式一般为 promise 对象
    //await 返回的是 promise 的 成功的值
    //await 后面的 promise 如果失败了 就会抛出异常 需要有 try catch 来捕获
   //await 后面当然 也可以跟返回结果 非 promise 表达式,比如 3 那么 let res = await e // res 的结果就是3 不会报错
let res; try { //resolve("success la") 走这里 // res 为 resolve() 里面的 结果的类型 res = await new Promise(function(resolve,reject){ // resolve("success la") reject("failure la") }) } catch (error) { //reject("failure la") 走这里 // res 是 string 类型 res = error; } console.log(typeof res); return res; } console.log(ac())
//应用
let fs = require("fs")
function readFile(path){
    return new Promise(function(resolve,reject){
        fs.readFile(path,function(error,data){
            if(error) reject(error);
            else resolve(data.toString())
        })
    })
    
}
async function readMn(){
    let res;
    try {
        let pre = await readFile("./minnongPre1.txt");
        let suf = await readFile("./minnongSuf.txt");
        res = pre + suf;
    } catch (error) {
        res = error;
    }
    return res;
}
readMn().then((data)=>{console.log(data)});

 19.关于正则的regexp的一些用法

//正则命名分组 普通的正则分组 exec执行后 res[0] 是匹配到的全部 res[1] 开始是分组匹配到的内容 index:2 表示从2开始匹配到
//groups 如果没有命名分组 那么是 undefined 如果是命名分组
let str = "ccname:武松8sjfsjf332age:83fwefi99" +
            "ccname:林冲8sjfsjf332age:82fwefi99"

let reg = /name:(?<name>.*?)8.*?age:(?<age>.*?)fw/sg;
let res = reg.exec(str)
console.log(res)
//显示分组后的内容 以分组时候给的名字作为 groups中的key
console.log(res.groups.name)
//正向断言和反向断言 a(?=bbb) (?<=bbb)a 不作为匹配返回结果 不作为子匹配
//正向反断言和反向反断言 a(!bbb) (?<!bbb)a 
let str = "ccname:武松打狗888sjfsjf332age:83fwefi99" +
            "ccname:武松打虎999sjfsjf332age:82fwefi99"
let str2 = "武松英雄"
let reg = /武松(?=英雄)/;
// let reg = /name:(?<name>.*?)8.*?age:(?<age>.*?)fw/sg;
let res = reg.exec(str)
console.log(res) //没有匹配到 null
res = reg.exec(str2)
console.log(res) //匹配到了 武松 后面的 英雄不是返回结果
console.log("---------------------------");
//?: 则需要理解捕获分组和非捕获分组的概念 这里是不捕获 分组 也就是不把分组存储在 $n 中
reg = /武松(?:英雄)/;
res = reg.exec(str2)
console.log(res) //res[0] 武松英雄,不存在 res[1]
console.log("---------------------------");
//关于不捕获分组的经典例子 数字格式化 1,123,000
//关于下面正则的理解 首先 对于 \b 是单词边界 像 空格 逗号 这些符合认知中的单词分割都属于边界 \B 是非单词边界
//所以像 \b \B 这种有两种匹配 1.单词 2.位置(就是边界,比较空的东西 看不到 用 console 查看就是一个空的字符串)
//下面的正则就是寻找一个 非单词边界 并且 (?=) 后面断言 必须是 非捕获匹配的 3 个数字 可以重复多次 (?:\d{3})+
//并且 最后不能是数字  (?!\d) 像 1234242fff 都可以替换后变成 1,234,242fff  (?!\d)也可以替换成 \b 单词边界 能处理 12345678这种 无法处理 12345678aaff
 str = "1234567890968fwefwff";
 reg = /\B(?=(?:\d{3})+(?!\d))/;
 res = reg.exec(str);
console.log(res);
console.log("---------------------------");
let  reg_split =/\B(?=(?:\d{3})+(?!\d))/
// let reg_split = /\B(?=(?:\d{3})+\b)/g;
res = str.replace(reg_split,",") // 结果:1,234,567,890,匹配的是后面是3*n个数字的非单词边界(\B)
console.log(res)
res = res.replace(reg_split,",") // 结果:1,234,567,890,匹配的是后面是3*n个数字的非单词边界(\B)
console.log(res)
//dotAll匹配模式 /s 默认正则是 . 匹配除了换行之外的任意字符 有时候为了让他匹配换行需要加入 s参数 呼吁事故dotAll 模式
let str = `name:张三3223
age:63aaaaa
name:李四3223
age:29aaaaa
`
let reg = /name:(.*?)\d+.*?age:(\d+)[a-z]+/g;
let res = reg.exec(str);
console.log(res)
//开启dotAll模式后 就可以匹配到了
//另外如果不使用matchAll 需要用 循环的模式 当匹配到null 结束 来匹配所有数据
let reg2 = /name:(.*?)\d+.*?age:(\d+)[a-z]+/gs;
while(res = reg2.exec(str)){
    console.log(res)
}
//matchAll模式
console.log("------------------------------------------");
res = str.matchAll(reg2);
console.log(res);
//res结果是一个迭代器 iterator 支持 for of 和 next
for(let k of res){
    console.log(k)
}
console.log("------------------------------------------");
//用next的模式获取一次 返回一个对象{done:false,value:xxx} value是数值 没有数据后返回  {done:true,value:undefined} 
res = str.matchAll(reg2);
console.log(res)
let r;
do {
    r = res.next()
    console.log(r);
} while (!r.done);

 20.关于文本String的一些用法

 //trimStart trimEnd trim 去掉空格 也没什么说的 

 21.关于this的研究

//globalThis 在不同平台是不同的 在chrome是window //在nodeJS平台上是 global 

posted @ 2023-02-25 16:28  闭区间  阅读(22)  评论(0编辑  收藏  举报