一.ES6新特性(重):
1. let 声明变量:
ES6新增加了两个重要的 JavaScript 关键字: let 和 const。
书写格式:
let a;
let b,c;
let d=10,f='asd',e=[];
注意事项:
1.变量不能重复声明:
let a=12;
let a=13;
运行结果:
2. 只在块级作用域内有效:
{
let a=12;
}
console.log(a);
运行结果:
3.不存在变量提升:
console.log(a);
let a=12;
运行结果:
4.不影响作用域链效果:
{
let blog = 'night';
function fn(){
console.log(blog);
}
fn();
}
运行结果:
案例:点击盒子切换颜色:
无法实现:
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
let items = document.querySelectorAll('.item');
// var声明
for(var i=0;i<items.length;i++){
items[i].onclick = function(){
items[i].style.background = 'blue';
}
}
</script>
运行结果:
因为var是全局作用域,到最后 i==3了。
可以实现:
//let声明
for(let i=0;i<items.length;i++){
items[i].onclick = function(){
items[i].style.background = 'blue';
}
}
运行结果:
因为let只在各自的块级作用域里有效,所以能使用。所以循环条件里建议用let声明。
2.const 声明常量:
格式(都一样的):
const BLOG = ‘night’;
注意事项:
1.一定要有初始值:
const BLOG;
运行结果:
2.一般声明使用大写(潜规则):
const BLOG = ‘night’;
3.常量值不能修改:
const BLOG='night';
BLOG = 'sky';
运行结果:
4.也是块级作用域内有效:
{
const BLOG='night';
}
console.log(BLOG);
运行结果:
5. 对于对数组和对象里元素修改,不算对常量进行修改 (因为地址没改变):
const arr= [1,2,3];
arr.push(4);
3.变量解构赋值:
解构赋值是对赋值运算符的扩展。他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
1.数组的解构:
const NATURE = ['sky','sea','tree'];
var [a,b,c] = NATURE;
console.log(a);
console.log(b);
console.log(c);
运行结果:
2.对象的解构:
const P = {
name:'night',
age:'22',
word:function(){
console.log("I am night");
}
};
let {name,age,word} = P;
console.log(name);
console.log(age);
console.log(word());
注意:变量名与对象里元素的名要一样的,且不论顺序如何也会一一对应。
运行结果:
3.模板字符串:
模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。
格式:
let night = `xiaoming`;
注意事项:
1.内容里可以出现换行符,如:
let star = `<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div> `;
不会报错。" "与 ’ ’ 这样写的话会。
2.可进行变量拼接:
let night = `xiaoming`;
let blog = `I am ${night}`;
console.log(night);
console.log(blog);
运行结果:
4.对象简化写法:
let name = 'xiaoming';
let age = '22';
let word = function(){
console.log("hello world");
}
var people = {
name:name,
age:age,
word:word,
out:function() {
console.log("北极光之夜。");
}
}
console.log(people);
可以简化成(注意对象里的变化):
let name = 'xiaoming';
let age = '22';
let word = function(){
console.log("hello world");
}
var people = {
name,
age,
word,
out() {
console.log("北极光之夜。");
}
}
console.log(people);
运行结果:
5. 箭头函数:
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
1.声明:
原先:
let item = function(a,b){
return a+b;
}
简写:
let item = (a,b)=>{
return a+b;
}
可以理解成去掉了function这个单词,参数后面多了个箭头表示。
注意事项:
1.this是静态的,this始终指向函数声明时所在作用域下的this值:
//全局
window.name = 'night';
//对象里的
var peopel = {
name:'sky'
}
//普通函数
function getName1(){
console.log(this.name);
}
//箭头函数
let getName2 = ()=>{
console.log(this.name);
}
//分别调用
getName1.call(peopel);
getName2.call(peopel);
使用 call() 方法,您可以编写能够在不同对象上使用的方法。
运行结果:
看出getName1的this指向已经变了,不再是全局的name,而是对象里的name,而箭头函数getName2没变,因为它始终指向函数声明时所在作用域下的this值。
2.不能作为构造实例化对象:
let night = (a,b)=>{
this.a=a;
this.b=b;
}
let out = new night();
console.log(out);
运行结果:
3. 不能使用arguments变量:
略…
4.箭头函数简写:
(1)当形参仅仅只有一个时可以省略括号:
let night = (n)=>{
return n+1;
}
相当于:
let night = n=>{
return n+1;
}
(2)当代码体只有一条语句时,可以省略花括号,且return这个单词也要省略:
let night = n=> n+1;
案例:
点击盒子两秒后变色:
<div class="item"></div>
<script>
var item = document.querySelector('.item');
item.onclick = function(){
//保存当前this
let _this = this;
setTimeout(function(){
_this.style.background = 'blue';
},2000)
}
</script>
我们这里可以看到要保存this,然后在定时器里才能用this,否则它会指向全局。
而使用箭头函数就不用这样,因为箭头函数this始终指向函数声明时所在作用域下的this值,如下:
var item = document.querySelector('.item');
item.onclick = function(){
/* let _this = this; */
setTimeout(()=>{
this.style.background = 'blue';
},2000)
}
运行结果:
6.函数参数的默认值设置:
1.允许给函数参数赋初始值(潜规则是有初始值的参数要放最后一个):
let add = (a,b,c=5)=>{
return a+b+c;
}
console.log(add(1,2));
运行结果:
7. rest参数:
新增的 rest参数 用来获取函数的实参,代替arguments
ES5方式(得到对象):
function arr(){
console.log(arguments);
}
arr('sky','sea','tree');
运行结果:
ES6方式(得到数组):
function arr(...night){
console.log(night);
}
arr('sky','sea','tree');
运行结果:
注意如果有多个参数,rest参数要放最后。
8.扩展运算符:
“…” 扩展运算符能将 “数组” 转换为逗号分隔的参数序列,如:
var arr = ['sea','sky','tree'];
function night(){
console.log(arguments);
}
night(...arr);
运行结果:
看到没,传入的参数不是一整个arr数组了,转换成三个参数了。
相当于这么传:
night('sea','sky','tree');
应用:
合并两个数组:
ES5写法:
var arr = ['sea','sky','tree'];
var item = ['nature','moon','wind'];
var world = arr.concat(item);
运行结果:
ES6写法(就问你快不快):
var arr = ['sea','sky','tree'];
var item = ['nature','moon','wind'];
var world = [...arr,...item];
数组克隆:
var arr = ['sea','sky','tree'];
var world = [...arr];
一个字,快!
伪数组转成真数组:
//伪数组
var arr = document.querySelectorAll("div");
//变真了
var world = [...arr];
9. Symbol:
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。且Symbol值不能与其他数据进行运算。且Symbol定义的对象属性不能使用fr…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。
创建:(会返回一个symbol对象)
let a = Symbol();
写入字符串,相当于描述注释这东西:
let a = Symbol('It is a');
也可以这样,返回函数对象:
let a = Symbol.for('It is a');
你看不到它独一无二,其实暗地里它已经由自己的某些方法让自己独一无二了。都会生成唯一的symbol值。
使用(给对象添加独一无二的属性和方法):
let people = {
name: 'night',
[Symbol('age')]: function(){
console.log("I am 22");
},
[Symbol('sex')]:function(){
console.log("I am man");
}
}
console.log(people);
运行结果:
10. 迭代器:
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口(其实就是对象里的一个属性),就可以完成遍历操作。
1.ES6创造了一种新的遍历命令fo…of 循环,Iterator接口主要供 for…of消费。
2.原生具备 iterator 接口的数据可用 for of 遍历。比如数组等都有。
let arr = ['sea','moon','wind'];
for(let v of arr){
console.log(v);
}
运行结果:
插一嘴,for in 循环保存的是键名。for of 保存的是键值。
案例:
const world = {
say:"hello",
items:['wind','sea','sky','star'],
[Symbol.iterator](){
//索引变量
let index = 0;
let _this = this;
return{
next:function(){
if(index<_this.items.length){
const result = {value:_this.items[index],done:false};
index++;
return result;
}else{
return {value:undefined,done:true};
}
}
}
}
}
for(let v of world){
console.log(world);
}
11.生成器:
其实就是一个特殊的函数。
在 javascript 中,如果想要使用生成器,则需要:
1.定义特殊的生成器函数(有个*号)。
2.调用该函数创建一个生成器对象。
3.在循环中使用该生成器对象,或直接调用其 next 方法。
function * fan(){
console.log('ha ha ha');
yield 'hahaha';
console.log('la la la');
yield 'lalala';
}
let ha = fan();
ha.next();
ha.next();
yield 关键字用来暂停和恢复一个生成器函数,就是代码分隔符。
运行结果:
12.promise:
Promise 是ES6引入的在 js 中进行异步编程的新解决方案。
或者promise详细使用请查看此链接:https://bbs.huaweicloud.com/blogs/258414
13. Set(集合):
ES6提供了新的数据结构Set(集合) 。它类似于数组,但成员的值都是唯一的,集合实现了iterator 接口,所以可以使用【扩展运算符】和【for…of…】进行遍历,集合的属性和方法:
- size 返回集合的元素个数。
- add 增加一个新元素,返回当前集合。
- delete 删除元素,返回boolean 值。
- has 检测集合中是否包含某个元素,返回boolean值。
- clear 清空数组。
声明:
let a1 = new Set();
let a2 = new Set(['star','moon','sea']);
console.log(a1);
console.log(a2);
运行结果:
方法:
let a2 = new Set(['star','moon','sea']);
//大小
console.log(a2.size);
//查找
console.log(a2.has('sea'));
运行结果:
应用:
定义一个数组:
let arr = [1,2,3,4,5,4,3,2,1];
- 数组去重:
let result = [...new Set(arr)];
- 交集:
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [1,2,3,6];
let result = [...new Set(arr)].filter(item=>{
let s = new Set(arr2);
if(s.has(item)){
return true;
}else{
return false;
}
})
console.log(result);
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
运行结果:
14.Map:
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator 接口,所以可以使用[扩展运算符」和[for…of…]进行遍历。Map的属性和方法:
- size 返回Map的元素个数。
- set 增加一个新元素,返回当前Map。
- get 返回键名对象的键值。
- has 检测Map中是否包含某个元素,返回boolean值。
- clear 清空集合,返回undefined。
例如(声明):
let m =new Map();
//新添元素,一个是键,一个是键值
m.set('name','北极光之夜。');
m.set('say',function(){
console.log("hello");
})
console.log(m);
运行结果:
15.class类:
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
知识点:
- class 声明类。
- constructor 定义构造函数初始化。
- extends。继承父类。
- super 调用父级构造方法。
- static定义静态方法和属性。
- 父类方法可以重写。
ES5构造实例化对象写法:
function Phone(price,processor){
this.price = price;
this.processor = processor;
}
//添加方法
Phone.prototype.advert=function(){
console.log("米西米西");
}
// 实例化对象
let phone = new Phone('5000','good');
phone.advert();
console.log(phone);
运行结果:
ES6 class类定义:
class Phone{
//构造方法,固定使用constructor
constructor(price,processor){
this.price = price;
this.processor = processor;
}
//添加方法,固定写法
advert(){
console.log("米西米西");
}
}
// 实例化对象
let phone = new Phone('5000','good');
phone.advert();
console.log(phone);
运行结果:
静态属性:
若有 static 定义的属性和方法只属于类,不属于实例对象:
class Phone{
static say = 'hello';
static advert(){
console.log("米西米西");
}
}
let phone = new Phone();
console.log(phone.say);
phone.advert();
运行结果:
构造函数继承:
//有一个构造函数
function People(name,age){
this.name = name;
this.age = age;
//它有一个say函数方法
this.say = function(){
console.log('哈哈哈,你也能用我啦~');
}
}
// 空的构造方法
function Xiaoming(){}
// 我想让Xiaoming也有People里面的say方法。
// 利用原型链机制,让一个引用类型继承另一个引用类型的属性和方法
Xiaoming.prototype = new People('小明',18);
var xiaoming = new Xiaoming();
xiaoming.say();
运行结果:
类继承:
class Phone{
constructor(price,processor){
this.price = price;
this.processor = processor;
}
advert(){
console.log("米西米西");
}
}
// extens关键字继承父类
class huawei extends Phone{
constructor(price,processor,color){
//继承父类构造方法
super(price,processor);
this.color = color;
}
say(){
console.log("hello world");
}
}
let hw = new huawei('5000','good','white');
hw.advert();
hw.say();
console.log(hw);
运行结果:
16. 数值扩展
Number . EPSILON 是JavaScript 表示的最小精度
EPSILON 属性的值接近于2. 2204460492503130808472633361816E-16
- 二进制和八进制
- Number. isFinite检测-一个数值是否为有限数。
- Number .isNaN 检测一个数值是否为 NaN。
- Number.parseInt Number.parseFloat字 符串转整数。
- Number. isInteger判断一个 数是否为整数。
- Math. trunc 将数字的小数部分抹掉。
- Math.sign判断一个数到底为正数负数还是零。
这个就不细写,用到哪个百度就好~
17.对象方法扩展:
Object.is()判断两个数值是否相等:
console.log(Object.is(5,5));
运行结果:
Object.assign对象合并
Object.assign(night,item);
放入两个对象就行。
18.模块:
什么是模块?
当一个js文件可以独立完成一个功能的时候,这个js文件就是一个模块。
当一个多个.js文件共同完成一个功能的时候,这个些js文件就是一个模块。
模块就是module (模块的意思)。
模块可以看这篇文章的第六点,很详细~
或者这篇文章的第六点,很详细:https://bbs.huaweicloud.com/blogs/269816
二.ES7新特性:
1. includes():
includes方法检测数组是否包含某个元素,返回布尔类型值。
var world = ['sea','wind','moon'];
console.log(world.includes('sea'));
运行结果:
2.指数操作符:
指数运算符 ** 可以快速实现次方运算,与Math.pow方法结果一样:
console.log(2 ** 3);
运行结果:
三.ES8新特性:
1.async 与 await:
async与await使用请点击链接看该文章的第十一与第十二点与第十三点~
或者查看该文章的第十一与第十二点与第十三点:https://bbs.huaweicloud.com/blogs/258414
2. 对象方法扩展:
Object.keys()获取对象所有的键:
var people = {
name:'nignt',
age: '22',
like:['sea','star','wind']
}
console.log(Object.keys(people));
运行结果:
Object.values()获取对象所有的值:
var people = {
name:'nignt',
age: '22',
like:['sea','star','wind']
}
console.log(Object.values(people));
运行结果:
Object.entries()获取对象所有的键与值:
配合Map()使用更佳:
var people = {
name:'nignt',
age: '22',
like:['sea','star','wind']
}
var m = new Map(Object.entries(people))
console.log(m);
运行结果:
对象属性描述对象:
Object.getOwnPropertyDescriptors();
var people = {
name:'nignt',
age: '22',
like:['sea','star','wind']
}
console.log(Object.getOwnPropertyDescriptors(people));
运行结果:
三.ES9新特性:
1.对象展开:
Rest参数与spread 扩展运算符在ES6 中已经引入,不过ES6 中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符。
如下:
function connect({one,two,...more}){
console.log(one);
console.log(two);
console.log(more);
}
connect({one:1,two:2,three:3,six:6})
运行结果:
应用:
合并几个对象里的属性:
var one = {
a:'sea'
}
var two = {
b:'star'
}
var three = {
c:'night'
}
var sum = {...one,...two,...three};
console.log(sum);
运行结果:
四.ES10新特性:
1.Object.fromEntries()
Object.fromEntries() 方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。
传入二维数组形式:
var sum = Object.fromEntries([
['name','sky'],
['age','22']
]);
console.log(sum);
看结果:
传入Map形式:
const m =new Map();
m.set('age','22');
var sum = Object.fromEntries(m);
console.log(sum);
结果:
2.trimStart()与trimEnd():
trimStart与trimEnd方法。
trimStart() 方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
trimEnd()方法从字符串末尾删除空格。trimRight()是此方法的别名。
var sum = " 北极光之夜。 ";
console.log(sum);
console.log(sum.trimStart());
console.log(sum.trimEnd());
运行:
3.flat与flatMap:
flat(n) 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。n表示深度,可将多维数组转成低维。
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与map连着深度变量1的 flat 几乎相同,但 flatMap通常在合并成一种方法的效率稍微高一些。
const arr = [1,2,[3,4]];
console.log(arr.flat());
运行:
五.ES11新特性:
好家伙终于到ES11了。一杯茶搞定看来还是有点玄呀。
1.私有属性:
在类里的私有属性前加个#号。就是说在这个类外部查找不到私有属性,只能在这个类的内部,来找到这个私有属性。
class people{
name;
#age;
constructor(name,age){
this.name =name;
this.#age = age;
}
out(){
console.log(this.#age);
}
let ha = new people();
console.log(ha.#age);
结果:
2.Promise.allSettled():
Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。而它的返回结果始终会是成功。
当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用它。
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('yes!!')
},500)
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('No!!')
},500)
})
let results = Promise.allSettled([p1,p2]);
console.log(results);
运行:
3.matchAll() :
matchAll() 方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。
4.可选链操作符
可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
5.BigInt:
BigInt 是一种内置对象,它提供了一种方法来表示大于 253 - 1 的整数。这原本是 Javascript中可以用 Number 表示的最大数字。BigInt 可以表示任意大的整数。
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数BigInt()。
主要运用于大数值的运算。
//最大安全整数
let max = Number.MAX_SAFE_INTEGER;
// 超过最大安全整数仍然能计算
console.log(BigInt(max)+BigInt(2));
结果:
6.globalThis:
全局属性 globalThis 包含全局的 this 值,类似于全局对象(global object。意思就是不管如何,它始终指向全局对象。
六.总结:
666,一杯茶到这也该喝完了~
还是有许多新特性没列举出来的,学无止境呀~
有帮助的话就点个赞和关注吧~