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 声明的变量有几个特点:
-
不允许重复声明
var s = "王小二"; var s = "李小三";let name = '王小二'; let name = '李小三'; // Uncaught SyntaxError: Identifier 'name' has already been declared
-
块儿级作用域
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
-
不存在变量提升
// 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 声明有以下特点
-
声明必须赋初始值
const A; // Uncaught SyntaxError: Missing initializer in const declaration
-
标识符一般为大写(潜规则, 不是必须的)
-
不允许重复声明
const GOODS = '书包'; const GOODS = '钢笔'; // Uncaught SyntaxError: Identifier 'GOODS' has already been declared
-
块儿级作用域
{const NAME = '王小二'; } console.log(NAME); // Uncaught ReferenceError: NAME is not defined
-
值不允许修改
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)是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符
- 可以使用 ${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.新增方法
-
startsWith()
:判断字符串是否以特定的字符开头。 -
endsWith()
:判断字符串是否以特定的字符结尾。 -
includes()
:判断字符串是否包含特定的字符。 -
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)
-
( 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
-
Object.values()方法返回一个给定对象的所有可枚举属性值的数组
-
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 的属性和方法
-
size 返回 Map 的元素个数
-
set 增加一个新元素,返回当前 Map
-
get 返回键名对象的键值对数组
-
has 检测 Map 中是否包含某个元素,返回 boolean 值
-
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.集合的常用属性和方法
-
size 返回集合的元素个数
-
add 增加一个新元素,返回当前集合
-
delete 删除元素,返回 boolean 值
-
has 检测集合中是否包含某个元素,返回 boolean 值
-
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);
相关文章:

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 声明的…...

动态DP入门线性动态DP
动态DP入门&线性动态DP 前言核心思想例1例22024牛客寒假4K2022牛客寒假2J结论 前言 OI-WiKi上有一个动态DP讲解,直接讲到了树型DP领域,同时需要树链剖分,门槛有点高。本文针对线性DP做一个动态DP的讲解。 首先当然要懂得一定的DP的相关…...

基于python+django+vue.js开发的停车管理系统
功能介绍 平台采用B/S结构,后端采用主流的Python语言进行开发,前端采用主流的Vue.js进行开发。 功能包括:车位管理、会员管理、停车场管理、违规管理、用户管理、日志管理、系统信息模块。 源码地址 https://github.com/geeeeeeeek/pytho…...

网站管理新利器:免费在线生成 robots.txt 文件!
🤖 探索网站管理新利器:免费在线生成 robots.txt 文件! 你是否曾为搜索引擎爬虫而烦恼?现在,我们推出全新的在线 robots.txt 文件生成工具,让你轻松管理网站爬虫访问权限,提升网站的可搜索性和…...

【Java程序员面试专栏 Java领域】Java虚拟机 核心面试指引
关于Java 虚拟机部分的核心知识进行一网打尽,主要包括Java虚拟机的内存分区,执行流程等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 JVM 程序执行流程 包括Java程序的完整执行流程,以及Javac编译,JIT即时编译 Java程序的完整执…...

洛谷C++简单题小练习day15—计算阶乘小程序(不用循环)
day15--计算阶乘小程序--2.19 习题概述 题目描述 求 n!,也就是 123⋯n。 挑战:尝试不使用循环语句(for、while)完成这个任务。 输入格式 第一行输入一个正整数 n。 输出格式 输出一个正整数,表示 n! 代码部分 …...

Vue报错,xxx is defined #变量未定义
vue.js:5129 [Vue warn]: Error in v-on handler: "ReferenceError: count is not defined" 浏览器将这个变量 当做全局变量了,事实上它只是实例中的变量 加上this指定,是vue实例中的变量...

Idea启动Gradle报错: Please, re-import the Gradle project and try again
Idea启动Gradle报错:Warning:Unable to make the module: reading, related gradle configuration was not found. Please, re-import the Gradle project and try again. 解决办法: 开启步骤:View -> Tool Windows -> Gradle 点击refe…...

Python函数(一)
目录 一、定义函数 (一)向函数传递信息 (二)实参和形参 二、传递实参 (一)位置实参 (二)关键字实参 (三)默认值 (四)等效的函…...

Excel表的内容批量生成个人加水印的Word文档
Excel表的内容批量生成个人加水印的Word文档 以下代码可以直接复制到docm文件里使用 Sub 宏1()Dim MyDialog As FileDialogDim GetStr As String, Adoc As StringDim PsDoc As DocumentApplication.ScreenUpdating FalseSet MyDialog Application.FileDialog(msoFileDialogF…...

微服务设计:Spring Cloud API 网关概述
Spring Cloud API 网关是指一个位于微服务架构中的代理服务器,它负责将外部请求路由到内部微服务。API 网关可以提供多种功能,包括: 路由: 将请求路由到特定的微服务。负载均衡: 将请求分散到多个微服务实例上。安全: 身份验证、授权和安全策…...

stm32学习笔记-STLINK使用
stm32学习笔记-STLINK使用 使用ST-LINK调试程序进度表格 使用ST-LINK调试程序 说明 组成 总结 记录使用STLINK进行项目的烧写和调试,旨在高效的进行代码调试学习工具包括笔记本、keil5MDK、stm32f030c8t6电表主机、STLINK V2、导线、电表代码总的来说࿰…...

Linux CentOS stream 9 firewalld
随着互联网行业快速发展,服务器成为用户部署网络业务重要的网络工具,但随之而来的就是更密集的网络攻击,这给网站带来了很大的阻碍。防火墙作为保障网络安全的主要设备,可以很好的抵御网络攻击。 防火墙基本上使用硬件和软件两种…...

VLM多模态图像识别小模型UForm
参考:https://github.com/unum-cloud/uform https://huggingface.co/unum-cloud/uform-gen2-qwen-500m https://baijiahao.baidu.com/s?id=1787054120353641459&wfr=spider&for=pc demo:https://huggingface.co/spaces/unum-cloud/uform-gen2-qwen-500m-demo UF…...

我的NPI项目之设备系统启动(七) -- 高通OS启动阶段和镜像分区简析
每当有新的平台起来的时候,大概率会伴随着新系统的发布,无论是高通的还是Google Andorid的。在做平台Bringup阶段总会遇到各种各样的专业术语。例如,总是会听到有人说PBL,SBL,XBL,UFEI,Bootload…...

vue框架-vue-cli
vue-cli Vue CLI是一个官方的脚手架工具,用于快速搭建基于Vue.js的项目。Vue CLI提供了一整套可配置的脚手架,可以帮助开发人员快速构建现代化的Web应用程序。 Vue CLI通过提供预先配置好的Webpack模板和插件,使得开发人员可以在不需要手动编写Webpack配置的情况下快速创建…...

Sora (text-to-video model-文本转视频模型)
以下翻译自维基百科 Introduction Sora 是由美国人工智能 (AI) 研究组织 OpenAI 开发的文本到视频模型。它可以根据描述性提示生成视频,并及时向前或向后扩展现有视频。截至 2024 年 2 月,它尚未发布,尚未向公众开放。 History 在 Sora 之…...

java生态环境评价Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java 生态环境评价管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq…...

数据结构-最短路径(Dijkstra算法与Floyd算法)
介绍 对于网图来说,最短路径是指两顶点之间经过的边上权值之和最少的路径,其路径上第一个点记为源点,最后一个为终点。 计算最短路径有两个经典算法,即迪杰斯特拉(Dijkstra)算法与弗洛伊德(Fl…...

文献速递:GAN医学影像合成--联邦生成对抗网络基础医学图像合成中的后门攻击与防御
文献速递:GAN医学影像合成–联邦生成对抗网络基础医学图像合成中的后门攻击与防御 01 文献速递介绍 虽然深度学习在医疗保健研究中产生了显著影响,但其在医疗保健领域的影响无疑比在其他应用领域更慢、更有限。造成这种情况的一个重要原因是ÿ…...

Java实现自动化pdf打水印小项目 使用技术pdfbox、Documents4j
文章目录 前言源码获取一、需求说明二、 调研pdf处理工具word处理工具 三、技术栈选择四、功能实现实现效果详细功能介绍详细代码实现项目目录WordUtilsMain类实现部分:第一部分Main类实现部分:第二部分Main类实现部分:第三部分 资料获取 前言…...

hive load data未正确读取到日期
1.源数据CSV文件日期字段值: 2.hive DDL语句: CREATE EXTERNAL TABLE test.textfile_table1(id int COMMENT ????, name string COMMENT ??, gender string COMMENT ??, birthday date COMMENT ????,.......) ROW FORMAT SERDE org.apache.…...

C++ 遍历map的3中方法
方法1 #include <iostream> #include <string> #include <map> using namespace std;int main() {map<string, string> nameList {{"张三丰", "武当山"},{"张无忌", "光明顶"},{"张二蛋", "…...

redis 主从模式,sentinel 模式配置
编辑 sentinel.xml 和 redis.conf redis.conf 中核心是配置 bind 192.168.64.144 daemonize yes protected-mode no dbfilename redis-6379.rdb #默认dump.rdb replica-read-only yes # 自动2.6副本默认只读,也就是slave只有只读权限 replicationOf myapplicat…...

小型医院医疗设备管理系统|基于springboot小型医院医疗设备管理系统设计与实现(源码+数据库+文档)
小型医院医疗设备管理系统目录 目录 基于springboot小型医院医疗设备管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、职员信息管理 2、设备信息管理 3、库房信息管理 4、公告信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、…...

CSS学习(三)
目录: 1. CSS引入方式 1.1 三种样式表 1.2 内部样式表(嵌入式引入) 1.3 行内样式表(内联样式表) 1.4 外部样式表 1.5 总结 1. CSS引入方式 1.1 三种样式表 1.2 内部样式表(嵌入式引入) …...

CentOS7安装InfluxDB2简易教程
InfluxDB是一个开源的时间序列数据库,它专门用于处理大规模的时间序列数据。时间序列数据是在特定时间点上收集的数据,例如传感器数据、监控数据、应用程序日志等。 InfluxDB设计用于高效地存储、查询和分析大量的时间序列数据。它具有高性能、可扩展性和…...

数据库:信息存储与管理的关键
数据库:信息存储与管理的关键 数据库是现代信息系统中不可或缺的组成部分,它承担着存储、管理和检索数据的重要任务。本文将详细介绍数据库的定义、分类、作用以及特点。 1. 数据库的介绍 数据库是一个有组织的数据集合,用于存储和管理大量…...

极智芯 | 解读NVIDIA RTX5090 又是一波被禁售的节奏
欢迎关注我的公众号「极智视界」,获取我的更多技术分享 大家好,我是极智视界,本文分享一下 解读NVIDIA RTX5090 又是一波被禁售的节奏。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq 按 NVIDIA GPU …...

rtt的io设备框架面向对象学习-硬件rtc设备
目录 1.硬件rtc设备基类2.硬件rtc设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 硬件rtc和软件rtc设备是互斥的。因为它们的名字都叫"rtc",在对象容器中不允许重名。 1.硬件rtc设备基类 此层处于设备驱…...