当前位置: 首页 > news >正文

ECMAScript 6+ 新特性 ( 一 )

2.1.let关键字

为了解决之前版本中 var 关键字存在存在着越域, 重复声明等多种问题, 在 ES6 以后推出 let 这个新的关键字用来定义变量

//声明变量
let a;
let b,c,d;
let e = 100;
let f = 123, g = 'hello javascript', h = [];

let 关键字用来声明变量,使用 let 声明的变量有几个特点:

  1. 不允许重复声明

    var s = "王小二";
    var s = "李小三";let name = '王小二';
    let name = '李小三';  // Uncaught SyntaxError: Identifier 'name' has already been declared
    
  2. 块儿级作用域

    if else while for 语句 都可以定义代码块

    // for(var i = 0;i < 5; i++){
    //     console.log(i)
    // }
    // console.log( "i:", i ) // i 越域{let girl = '赵静子';
    }
    console.log(girl); // Uncaught ReferenceError: girl is not defined
    
  3. 不存在变量提升

    // console.log(s) // undefined
    // var s = "abc"
    // console.log(s) // abcconsole.log(song); //Uncaught ReferenceError: Cannot access 'song' before initialization
    let song = '最炫民族风';
    console.log(song)  // 不会再执行到这行
    

2.2. const 关键字

定义常量, 不能修改

//声明常量
const GOODS = '书包';

const 关键字用来声明常量,const 声明有以下特点

  1. 声明必须赋初始值

    const A;  // Uncaught SyntaxError: Missing initializer in const declaration
    
  2. 标识符一般为大写(潜规则, 不是必须的)

  3. 不允许重复声明

    const GOODS = '书包';
    const GOODS = '钢笔'; // Uncaught SyntaxError: Identifier 'GOODS' has already been declared
    
  4. 块儿级作用域

    {const NAME = '王小二';
    }
    console.log(NAME); // Uncaught ReferenceError: NAME is not defined
    
  5. 值不允许修改

    const BOOK = '三体';
    BOOK = '西游记'; // Uncaught TypeError: Assignment to constant variable.
    

    特别要注意 : 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错

    const TEAM = ['王小二','李小三'];
    TEAM.push('赵小四');const STU = {name: '王小二',age: 18
    }
    STU.name = '赵小四';
    

应用场景:声明对象类型使用const,非对象类型声明选择 let

2.3.变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

2.3.1.数组的解构赋值

const F4 = ['王小二','李小三','赵小四','张不开'];
// let wang = F4[0];
// let li = F4[1];
// let zhao = F4[2];
// let zhang = F4[3];let [ wang, li, zhao, zhang ] = F4;
console.log(wang);
console.log(li);
console.log(zhao);
console.log(zhang);

2.3.2.对象的解构赋值

const STU = {name: '王小二',age: 18,sayHello: function(){console.log("Hello, 我是" + this.name);}
};// let name = STU.name
// let age = STU.age;
// let sayHello = STU.sayHello;// let { name : name , age : age ,  sayHello : sayHello } = STU;
let { name, age, sayHello } = STU;
console.log(name);
console.log(age);
// console.log(sayHello);
sayHello();// let { sayHello } = STU;
// sayHello();// let { name : abc  } = STU;
// console.log(abc)

2.3.3.复杂解构

先定义对象

let wang = {like : ['运动','美食','音乐'],study:[{ name: 'java', info:'啥都能干'},{ name: 'HTML', info: '挺好学的'},{ name: 'javascript', info: '也啥都能干'}]
}
2.3.3.1.解构方式1
let {  like, study } = wang;
console.log( like );
console.log( like[0] );
console.log( like[1] );
console.log( like[2] );
console.log( study );
console.log( study[0].name );
console.log( study[0].info );
2.3.3.2.解构方式2

one , two, three, java, html, js 才是解构出来的变量

let {  like : [ one, two, three ] , study : [ java, html, js ] } = wang;
// console.log( like ); // 使用报错 :  Uncaught ReferenceError: like is not defined
console.log( one );
console.log( two );
console.log( three );console.log(java.name);
console.log(html.info);
console.log( js )
console.log( js.name )

注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式

2.4.字符串优化

2.4.1.模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:

  1. 字符串中可以出现换行符
  2. 可以使用 ${xxx} 形式输出变量
2.4.1.1.定义字符串
let s = `我也是一个字符串哦!`;console.log(s, typeof s);let str = `<ul><li>王小二</li><li>李小三</li><li>赵小四</li></ul>`;
console.log(str, typeof str);
2.4.1.2.输出变量
let zhao = '赵静子';
let out = `${zhao}是个大美女!!`;
console.log(out);

注意:当遇到字符串与变量拼接的情况使用模板字符串

2.4.2.新增方法

  1. startsWith():判断字符串是否以特定的字符开头。

  2. endsWith():判断字符串是否以特定的字符结尾。

  3. includes():判断字符串是否包含特定的字符。

  4. repeat():重复生成指定次数的字符串。

    let str = "hello.vue";
    console.log(str.startsWith("hello"));  //true
    console.log(str.endsWith(".vue"));  //true
    console.log(str.includes("e"));  //true
    console.log(str.includes("hello"));   //true
    let ss = str.repeat(3);    //hello.vuehello.vuehello.vue
    console.log(ss)
    
  5. ( ES 10 ) trimStart()trimEnd()

    let str = '   hello world   ';console.log(str);            // "   hello world   "
    console.log(str.trim() );    // "hello world"
    console.log(str.trimStart()); // "hello world   "
    console.log(str.trimEnd());   // "   hello world"
    

2.5.函数优化

2.5.1.箭头函数

ES6 允许使用「箭头」(=>)定义函数。

let fn1 = function(){console.log('function')
}
fn1()let fn2 = ()=>{console.log('=>')
};
fn2()
2.5.1.1.写法
// 声明一个函数
let fn = (a,b) => {return a + b;
}
// 调用函数
let result = fn(1, 2);
console.log(result);// 如果形参只有一个,则小括号可以省略
let fn3 = num => {return num * 10;
};// 函数体如果只有一条语句,则花括号可以省略
let fn4 = ()=>console.log('hello')// 函数的返回值为该条语句的执行结果
let fn5 = score => score * 20;
let result = fn5(10);
console.log(result)

箭头函数+解构

const person = {name: "jack",age: 21,language: ['java', 'js', 'css']
}function hello(person){console.log("hello," + person.name)
}//箭头函数+解构
var hello2 = ({name}) => console.log("hello," + name);
hello2(person);
2.5.1.2.this

this 指向声明时所在作用域中 this的值

// 设置 window 对象的 name 属性
window.name = '王小二';
let name = '赵静子';
console.log( this )
function getName(){console.log(this.name);
}let getName2 = () => {console.log(this.name);
}//直接调用
getName();  // 王小二
getName2();  // 王小二

注意:this 是静态的 , 箭头函数不会更改 this 指向,用来指定回调函数会非常合适

箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法

const STU = {name: "李小三"
}//call 方法调用
getName.call(STU); // 李小三
getName2.call(STU); // 王小二
2.5.1.3.不能作为构造函数

箭头函数不能作为构造函数实例化

let Sss = function (name, age) {this.name = name;this.age = age;
}
let wang = new Sss('王小二',12); 
console.log(wang);let Stu = (name, age) => {this.name = name;this.age = age;
}
let li = new Stu('李小三',13); //Uncaught TypeError: Stu is not a constructor
console.log(li);
2.5.1.4.不能使用 arguments
let fn6 = function () {console.log(arguments); 
}
fn6(1,2,3);let fn7 = () => {console.log(arguments);
}
fn7(1,2,3); //Uncaught ReferenceError: arguments is not defined

2.5.2. rest 参数(不定参数)

ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments

// ES5 获取实参的方式
// function getName1(){
//     console.log(arguments);
// }
// getName1('王小二','李小三','赵小四');// rest 参数
// function getName2(...args){
//     console.log(args);// filter some every map
// }
// getName2('王小二','李小三','赵小四');
// getName2('王小二','李小三');// rest 参数必须要放到参数最后
function fn(a,b,...args){console.log(a);console.log(b);console.log(args);console.log(args.length);
}
fn(1,2,3,4,5,6);

注意:rest 参数非常适合不定个数参数函数的场景

2.5.3. spread 扩展运算符

扩展运算符(spread)也是三个点(…)。

它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

// 声明一个数组 
const names = ['王小二','李小三','赵小四'];// 声明一个函数
function getName(){console.log(arguments);
}getName(...names); // getName('王小二','李小三','赵小四')

2.5.4.参数设置默认值

//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {// 判断b是否为空,为空就给默认值1b = b || 1;return a + b;
}
// 传一个参数
console.log(add(10));//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {return a + b;
}
console.log(add2(20));

2.5.5.( ES 11 )可选链操作符

使用参数之前 先判断参数有效性, 否则使用未传入的参数会报错

使用 ?. 运算符, 可以自动根据参数有效性进行判断, 如果参数无效, 不报错, 返回 undefined

// ?.
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'
//     }
// })
main();

2.6.对象Object优化

2.6.1.对象新的方法

2.6.1.1.结构分析
const STU = {name: "王小二",age: 21,language: ['java', 'js', 'vue']
}console.log( Object.keys(STU) );  //[ "name", "age", "language" ]
console.log( Object.values(STU) ); //[ "王小二", 21, Array(3) ]
console.log( Object.entries(STU) ); //[ Array(2), Array(2), Array(2) ]
2.6.1.2.判断完全相等
// Object.is 判断两个值是否完全相等 
console.log(Object.is(120, 120));// true
console.log(Object.is(120, '120'));// false
console.log(Object.is(NaN, NaN));// true
console.log(NaN === NaN);// false
console.log(NaN == NaN);// false
2.6.1.3.合并
const STU1 = {name : '王小二',age : 18,birth : '2001-01-01',info1: '一个好学生'
};
const STU2 = {name : '李小三',age : 22,sex : '女',info2: '也是一个好学生'
}Object.assign(STU1, STU2) // 将STU1和STU2合并到 STU1console.log( STU1 );
// 结果是合并结果
// {
//     age : 22,
//     birth : "2001-01-01",
//     info1 : "一个好学生",
//     info2 : "也是一个好学生",
//     name : "李小三",
//     sex : "女"
// }console.log( STU2 ); // 不变化
2.6.1.4.拷贝
// 1、拷贝对象(深拷贝)
let s1 = { name: "王小二", age: 15 }
let s2 = { ...s1 }
console.log( s2 ) //{ name:"王小二", age:15 }// 2、合并对象
let age1 = { age: 15 }
let name1 = { name: "王小二" }
let s3 = { name : "李小三" }
s3 = { ...age1, ...name1 }
console.log( s3 ) // {age: 15, name: '王小二'}
2.6.1.5.( ES 8 ) Object.values 和 Object.entries
  1. Object.values()方法返回一个给定对象的所有可枚举属性值的数组

  2. Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组

    //声明对象
    const STU = {name : "王小二",study : ['java','html','js']
    };//获取对象所有的键
    console.log(Object.keys(STU)); // ['name', 'study']
    //获取对象所有的值
    console.log(Object.values(STU)); // ['王小二', ['java', 'html', 'js']]
    //entries
    console.log(Object.entries(STU)); // [['name', '王小二'], ['study', ['java', 'html', 'js']]]//创建 Map
    const m = new Map(Object.entries(STU));
    console.log(m.get('study'));
    
2.6.1.6.( ES 9 )Object.fromEntries

从 二维数组 / Map 创建对象

//二维数组
const result1 = Object.fromEntries([['name','王小二'],['study', 'Java,html,js']
]);
console.log(result1) //{name: "王小二", study: "Java,html,js"}//Map
const m = new Map();
m.set('name','李小三');
m.set('like', ['电影','美食','旅游'] )
const result2 = Object.fromEntries(m);
console.log(result2); //{name: "李小三", like: Array(3)}
2.6.1.7.( ES 8 )Object.getOwnPropertyDescriptors

该方法返回指定对象所有自身属性的描述对象

数据属性:value(值)、writable(是否可写)、enumerable(是否可枚举)、configurable(是否可配置)

console.log(Object.getOwnPropertyDescriptors(STU));
// 输出 : 
// { 
//     name: { value: '王小二', writable: true, enumerable: true, configurable: true }, 
//     study: { value: [ 'java', 'html', 'js' ], writable: true, enumerable: true, configurable: true }
// }

也可以在创建时 指定这些属性

const obj = Object.create(null, {name: {//设置值value: '李小三',//属性特性writable: true,configurable: true,enumerable: true}
});
console.log(obj)

2.6.2.对象原型 ***

2.6.2.1.Object.setPrototypeOf()

在 JavaScript 中,__proto__ 和 Object.setPrototypeOf() 都是用来操作对象的原型链的。
__proto__ 是对象的一个内部属性,用于获取或设置对象的原型。可以通过访问器属性的方式来获取或设置 __proto__

const obj = {};
const proto = { hello: "world" };
obj.__proto__ = proto; // 设置 obj 的原型为 proto
console.log(obj.hello); // 输出 "world"

需要注意的是,__proto__ 属性在 ECMAScript 6 标准中被弃用,虽然现代浏览器仍然支持它,但不建议在生产环境中使用它。
因此,推荐使用 Object.setPrototypeOf() 方法来设置对象的原型。
Object.setPrototypeOf() 是一个静态方法,用于设置一个对象的原型。它接收两个参数:要设置原型的对象和要设置的原型对象。例如:

Object.setPrototypeOf() 方法会将第一个参数对象的原型设置为第二个参数的对象。
这样,第一个参数对象就能够继承第二个参数对象的属性和方法。
需要注意的是,频繁地改变对象的原型链会对性能产生负面影响。因此,除非必要,一般不建议经常性地改变对象的原型。

const obj = {};
const proto = { hello: "world" };
Object.setPrototypeOf(obj, proto); // 设置 obj 的原型为 proto
console.log(obj.hello); // 输出 "world"
2.6.2.2.Object.getPrototypeOf()

在 JavaScript 中,Object.getPrototypeOf() 是一个静态方法,用于获取指定对象的原型。
Object.getPrototypeOf() 方法接收一个参数,即要获取原型的对象。它会返回指定对象的原型。

const obj = {};
const proto = { hello: "world" };
Object.setPrototypeOf(obj, proto); // 设置 obj 的原型为 proto
const objPrototype = Object.getPrototypeOf(obj);
console.log(objPrototype); // 输出 { hello: "world" }

在上面的示例中,我们使用 Object.setPrototypeOf() 方法将 obj 的原型设置为 proto。
然后,通过 Object.getPrototypeOf() 方法获取了 obj 的原型,并将其赋值给 objPrototype。
需要注意的是,Object.getPrototypeOf() 方法返回的是指定对象的原型,即它的 [[Prototype]] 属性的值。
如果指定对象没有明确的原型,即它是通过 Object.create(null) 或者 null 构造的对象,
那么 Object.getPrototypeOf() 方法会返回 null。
Object.getPrototypeOf() 方法的应用场景包括,
判断对象是否继承了指定的原型,检查对象的原型链关系,以及执行一些基于对象原型的操作。

2.6.3.简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let name = '王小二';
let sayHello = function(){console.log('大家好!!');
}// const STU = {
//     name : name,
//     sayHello : sayHello,
//     study: function(){
//         console.log("我们一起学 js");
//     }
// }const STU = {name,sayHello,study(){console.log("我们一起学 js");}
}console.log(STU);
STU.sayHello()

几种对象函数的写法:

let person3 = {name: "王小二",// 以前:eat: function (food) {console.log(this.name + "在吃" + food);},//箭头函数this不能使用,对象.属性eat2: food => console.log(person3.name + "在吃" + food),// 匿名eat3(food) {console.log(this.name + "在吃" + food);}
}person3.eat("香蕉");person3.eat2("苹果")person3.eat3("橘子");

2.6.4.( ES 9 )Rest/Spread 属性

Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符

//rest 参数
function connect({host, port, ...user}){console.log(host);  // 127.0.0.1console.log(port);  // 3306console.log(user);  // { username: 'root', password: 'root', type: 'master' }
}connect({host: '127.0.0.1',port: 3306,username: 'root',password: 'root',type: 'master'
});
//对象合并
const teamOne = {a : '王小二',b : '李小三'
}const teamTwo = {c : '赵小四',d : '张不开',e : '刘小六'
}const team = {...teamOne,...teamTwo
}console.log(team) //{a: '王小二', b: '李小三', c: '赵小四', d: '张不开', e: '刘小六'}

2.7. 扩展Map

ES6 提供了 Map 数据结构。

它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

Map会按照插入的顺序来迭代元素,而对象中的键值对没有固定的顺序。

Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

2.7.1.创建和初始化

// 创建一个空 Map
let map1 = new Map();// 使用数组形式初始化 Map
let map2 = new Map([['name', '王小二'],[123, 'abc'],[{ key: 'objectKey' }, 'Value for object key']
]);
console.log(map2);
// 使用可迭代对象(如另一个 Map 或 Set)初始化
let obj = { a: 1, b: 2 };
let entries = Object.entries(obj);
let map3 = new Map(entries);console.log(map3); // Map(2) { 'a' => 1, 'b' => 2 }

2.7.2.Map 的属性和方法

  1. size 返回 Map 的元素个数

  2. set 增加一个新元素,返回当前 Map

  3. get 返回键名对象的键值对数组

  4. has 检测 Map 中是否包含某个元素,返回 boolean 值

  5. clear 清空集合,返回 undefined

//声明 Map
let m = new Map();//添加元素
m.set('name','王小二');
m.set('sayHello', function(){console.log("大家好!!");
});
let key = {study : 'JAVA'
};
m.set(key, ['spring','mybatis','springmvc']);//size
console.log(m.size);//删除
m.delete('name');
//获取
console.log(m.get('name'));
console.log(m.get('sayHello'));
console.log(m.get(key));//清空
// m.clear();//遍历
for(let v of m){console.log(v);
}console.log(m);

2.8.数组Array 扩展

在 ES6(ECMAScript 2015)中,JavaScript 对 Array 对象进行了多个重要扩展和改进,以增强数组操作的便利性和性能。

2.8.1.主要的 新特性

2.8.1.1.扩展运算符 (...)

可用于解构赋值、复制数组以及将数组转换为参数序列。

let arr1 = [1, 2, 3];
let arr2 = [...arr1]; // 复制数组:[1, 2, 3]
let combined = [0, ...arr1, 4]; // 合并数组:[0, 1, 2, 3, 4]
function logArgs(...args) {console.log(args);
}
logArgs(...arr1); // 输出:[1, 2, 3]
2.8.1.2.Array.from()

将类数组对象或可迭代对象转换为真正的数组。

let arrayLike = { 0: 'a', 1: 'b', length: 2 };
let arr = Array.from(arrayLike); // 转换为:['a', 'b']
2.8.1.3.Array.of()

根据传入的参数创建一个新数组。

let arr = Array.of(1, 2, 3); // 创建:[1, 2, 3]
2.8.1.4.( ES 7 )Array.prototype.includes()

检查数组是否包含某个指定的值。

let arr = [1, 2, 3];
console.log(arr.includes(2)); // 输出:true
2.8.1.5…参数与展开语法在数组方法中的应用

例如,在 Math.max()Math.min() 中可以使用剩余参数来替代 apply() 方法。

let maxNumber = Math.max(...arr); // 获取数组中的最大值
2.8.1.6.fill()

填充数组的方法,用给定值填充数组的一部分或全部。

let filledArr = new Array(5).fill('hello');
console.log(filledArr); // 输出:['hello', 'hello', 'hello', 'hello', 'hello']
2.8.1.7.( ES 10 ) flat() / flatMap()

将嵌套数组拉平为一维数组。

let arrs = [ [1,2,3], [4,5,6,7], [8,9,10] ];
console.log(arrs.length) //3// 将嵌套数组拉平为一维数组。
let arrs1 = arrs.flat()
console.log(arrs1.length) // 10
console.log(arrs1) // 10// 先对数组中的每个元素执行映射函数,然后将结果拉平为一维数组。
let arrs2 = arrs.flatMap( item => Math.max(...item) )
console.log(arrs2) 
2.8.1.8.copyWithin()

在数组内部的一个位置复制数组的一部分到另一个位置。

let copyArr = [1, 2, 3, 4, 5];
copyArr.copyWithin(0, 3); // 把从下标3开始的元素复制到下标0开始的位置:[4, 5, 3, 4, 5]

2.8.2.结合箭头函数

2.8.2.1.map()

map() 方法对数组中的每个元素执行给定的回调函数,并将回调函数的返回值组成一个新数组返回。

它可以用于对原始数组中的每个元素进行处理,并返回一个处理后的新数组。

let numbers = [1, 2, 3, 4, 5];
let squared = numbers.map(n => n * n); // 映射:[1, 4, 9, 16, 25]
2.8.2.2.reduce()

reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,

arr.reduce(callback,[initialValue])

callback () 的参数

1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)

let arr = [2, 40, -10, 6]
let result = arr.reduce( (a,b)=>{console.log("上一次处理后:" + a);console.log("当前正在处理:" + b);return a + b;
},100 );
console.log(result)//   运行结果// 上一次处理后:100
// 当前正在处理:2
// 上一次处理后:102
// 当前正在处理:40
// 上一次处理后:142
// 当前正在处理:-10
// 上一次处理后:132
// 当前正在处理:6
// 138
2.8.2.3.filter()

方法用于过滤数组中的元素,返回满足给定条件的新数组。

它可以通过指定一个回调函数来筛选出需要的元素,该方法返回一个新数组。

// 筛选出数组中偶数
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // 输出:[2, 4, 6, 8]// 从用户对象列表中筛选出年龄大于等于18岁的用户
let users = [{ id: 1, name: '王小二', age: 20 },{ id: 2, name: '李小三', age: 17 },{ id: 3, name: '赵小四', age: 22 },{ id: 4, name: '张不开', age: 16 }
];
let adults = users.filter(user => user.age >= 18);
console.log(adults);
// 输出:
// [
//   { id: 1, name: '王小二', age: 20 },
//   { id: 3, name: '赵小四', age: 22 }
// ]// 筛选非空字符串
let strings = ['apple', '', '张不开', null, undefined , '123'];
let nonEmptyStrings = strings.filter(str => str && str.trim().length > 0);
console.log(nonEmptyStrings);
// 输出:['apple', '张不开', '123']
2.8.2.4.find()

find(): 返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。

let arr = [ 1, 2, 3, 4, 5, 6]
let found = arr.find(item => item > 3); // 返回第一个大于3的元素
console.log( found )let foundIndex = arr.findIndex(item => item > 3); // 返回第一个大于3的元素
console.log( foundIndex )
2.8.2.5.迭代器方法

entries(), keys(), values() 提供了迭代器接口。

let arr = [ 1, 2, 3, 4, 5, 6]
for (let [index, value] of arr.entries()) {console.log(index, value);
}

2.9. 扩展Set

ES6 提供了新的数据结构 Set(集合)。

它类似于数组,但成员的值都是唯一的,

集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,

2.9.1.集合的常用属性和方法

  1. size 返回集合的元素个数

  2. add 增加一个新元素,返回当前集合

  3. delete 删除元素,返回 boolean 值

  4. has 检测集合中是否包含某个元素,返回 boolean 值

  5. clear 清空集合,返回 undefined

//声明一个 空 set
let s = new Set();
let s2 = new Set(['王小二','李小三','赵小四','张小三','李小三']);
console.log(s2);
// //元素个数
console.log(s2.size);
// //添加新的元素
s2.add('刘小六');
s2.add('王小二')
console.log(s2);
// //删除元素
s2.delete('张小三');
console.log(s2);
// //检测
console.log(s2.has('赵小四'));
// //清空
// s2.clear();
// console.log(s2);
//
for(let v of s2){console.log(v);
}

2.9.2.应用

let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
// let result = [...new Set(arr)];
// console.log(result);//2. 交集 has()
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;
//     }
// });
// // let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// console.log(result);//3. 并集
// let union = [...new Set([...arr, ...arr2])];
// console.log(union);//4. 差集
// let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
// console.log(diff);

2.10. 数值扩展

2.10.1.Number新增方法

2.10.1.1.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);
console.log(equal(0.1 + 0.2, 0.3))
2.10.1.2.二进制和八进制

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。

let b = 0b1010;  // 二进制
let o = 0o777;   // 八进制
let d = 100;     // 十进制
let x = 0xff;    // 十六进制
console.log(x);
2.10.1.3.Number.isFinite()

Number.isFinite() 用来检查一个数值是否为有限的

console.log(Number.isFinite(100));       // true
console.log(Number.isFinite(100/0));     // false
console.log(Number.isFinite(Infinity));  // false
2.10.1.4.Number.parseInt() 与 Number.parseFloat()

ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。

console.log(Number.parseInt('5211314love'));   // 5211314
console.log(Number.parseFloat('3.1415926神奇'));  // 3.1415926
2.10.1.5.Number.isInteger

Number.isInteger() 用来判断一个数值是否为整数

console.log(Number.isInteger(5));  // true
console.log(Number.isInteger(2.5));  // false

2.10.2.Math新增方法

2.10.2.1.Math.sign

判断一个数到底为正数 负数 还是零

console.log(Math.sign(100));  // 1
console.log(Math.sign(0));    // 0
console.log(Math.sign(-20000));  // -1
2.10.2.2.Math.trunc

用于去除一个数的小数部分,返回整数部分。

console.log(Math.trunc(3.5)); // 3
2.10.2.3.( ES 7 )幂运算新写法

在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同

 console.log(2 ** 10);// console.log(Math.pow(2, 10));

2.10.3.( ES 11 ) BigInt

更大的数据范围, 只能是整数

//大整形
let n = 521n;
console.log(n, typeof(n)); // 521n 'bigint'//函数
// let n = 123;
console.log(BigInt(n)); // 123n
console.log(BigInt(1.2)); // Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is not an integer//大数值运算
let max = Number.MAX_SAFE_INTEGER; // 9007199254740991
console.log(max); // 9007199254740991
console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740993console.log(BigInt(max)) // 9007199254740991n
console.log(BigInt(max) + BigInt(1)) // 9007199254740992n
console.log(BigInt(max) + BigInt(2)) // 9007199254740993n

2.11. ( ES 9 ) 正则表达式

2.11.1.( ES 9 ) 命名捕获组

同时 匹配多个信息, 之前的处理方式

//声明一个字符串
let str = '<a href="http://www.baidu.com">百度</a>';//提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;//执行
const result = reg.exec(str);console.log(result); 
// 输出:
// [
// '<a href="http://www.baidu.com">百度</a>',
// 'http://www.baidu.com', 
// '百度',
// index: 0, 
// input: '<a href="http://www.baidu.com">百度</a>', 
// groups: undefined
// ]
console.log(result[1]); // http://www.baidu.com
console.log(result[2]); // 百度

ES 9 允许命名捕获组使用符号 ?<name> ,这样获取捕获结果可读性更强

let str = '<a href="http://www.baidu.com">百度</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;const result = reg.exec(str);
console.log(result)
// 输出:
// [
// '<a href="http://www.baidu.com">百度</a>',
// 'http://www.baidu.com',
// '百度',
// index: 0,
// input: '<a href="http://www.baidu.com">百度</a>',
// groups:{ text:"百度", url:"http://www.baidu.com" },
// length : 3
// ]
console.log(result.groups.url); // http://www.baidu.com
console.log(result.groups.text); // 百度

2.11.2.( ES 9 )反向断言

ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。

//声明字符串
// let str = '电话号码13123456789年龄23岁';
let str = '电话号码13987654321年龄45岁';
//正向断言
const reg1 = /\d+(?=岁)/;
const result1 = reg1.exec(str);
console.log(result1);//反向断言
const reg2 = /(?<=年龄)\d+/;
const result2 = reg2.exec(str);
console.log(result2);

2.11.3.( ES 9 )dotAll 模式

正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,

允许行终止符出现

//dot  .  元字符  除换行符以外的任意单个字符
let str = `<ul><li><a>热辣滚烫</a><p>上映日期: 2024-02-10</p></li><li><a>你好, 李焕英</a><p>上映日期: 2021-02-12</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);

2.11.4.( ES 11 ) String.prototype.matchAll

得到 正则批量匹配结果

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);
http://www.lryc.cn/news/302559.html

相关文章:

  • 动态DP入门线性动态DP
  • 基于python+django+vue.js开发的停车管理系统
  • 网站管理新利器:免费在线生成 robots.txt 文件!
  • 【Java程序员面试专栏 Java领域】Java虚拟机 核心面试指引
  • 洛谷C++简单题小练习day15—计算阶乘小程序(不用循环)
  • Vue报错,xxx is defined #变量未定义
  • Idea启动Gradle报错: Please, re-import the Gradle project and try again
  • Python函数(一)
  • Excel表的内容批量生成个人加水印的Word文档
  • 微服务设计:Spring Cloud API 网关概述
  • stm32学习笔记-STLINK使用
  • Linux CentOS stream 9 firewalld
  • VLM多模态图像识别小模型UForm
  • 我的NPI项目之设备系统启动(七) -- 高通OS启动阶段和镜像分区简析
  • vue框架-vue-cli
  • Sora (text-to-video model-文本转视频模型)
  • java生态环境评价Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 数据结构-最短路径(Dijkstra算法与Floyd算法)
  • 文献速递:GAN医学影像合成--联邦生成对抗网络基础医学图像合成中的后门攻击与防御
  • Java实现自动化pdf打水印小项目 使用技术pdfbox、Documents4j
  • hive load data未正确读取到日期
  • C++ 遍历map的3中方法
  • redis 主从模式,sentinel 模式配置
  • 小型医院医疗设备管理系统|基于springboot小型医院医疗设备管理系统设计与实现(源码+数据库+文档)
  • CSS学习(三)
  • CentOS7安装InfluxDB2简易教程
  • 数据库:信息存储与管理的关键
  • 极智芯 | 解读NVIDIA RTX5090 又是一波被禁售的节奏
  • rtt的io设备框架面向对象学习-硬件rtc设备
  • 产品经理学习-产品运营《流程管理》