ES6-ES11

ES6

函数参数默认值
function add(a,b,c=10){
	return a + b + c;
}
let result = add(1,2);
console.log(result); // 13
rest 参数

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

function date(){
	console.log(arguments);
}
date('白芷','阿娇','思慧')
// Arguments(3) ['白芷', '阿娇', '思慧', callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 0: "白芷"
// 1: "阿娇"
// 2: "思慧"
// callee: ƒ date()
// length: 3
// Symbol(Symbol.iterator): ƒ values()
// [[Prototype]]: Object

rest参数

function date(...args){
	console.log(args);
}
date('白芷','阿娇','思慧') //['白芷', '阿娇', '思慧']
function fn(a,b,c,...args){
	console.log(a);
	console.log(b);
	console.log(args);
}
fn(1,2,3,4,5,63,2) 
// 1
// 2
// [4, 5, 63, 2]

ES6中的三个点 … 有两个名字:rest参数和扩展运算符.

  • 当用在函数定义时的形参前面时,称为rest参数,当函数调用时,用于接收不确定的参数.
  • 当与解构赋值组合使用时,称为rest参数,用于接收剩余的值,存储在数组中.
  • 当用在字符串或数组前面时称为扩展运算符,将数组或字符串进行拆解
// 扩展运算符的运用 
// 1.数组的合并
const kuaizi = ['王太利','肖央']
const fenghuang = ['曾毅','玲花']
const all = kuaizi.concat(fenghuang) // ['王太利', '肖央', '曾毅', '玲花']
const all1 = [...kuaizi,...fenghuang] // ['王太利', '肖央', '曾毅', '玲花']
// 2.数组的克隆
const sanzhihua = ['e','g','m'];
const sanyecai = [...sanzhihua];//['e','g','m']
// 3.将伪数组转为真正的数组
const divs = document.querySelectorAll('div')
const divArr = [...divs] // [div,div,div]

Symbol运算符

表示独一无二的值,他是JS语言的第7种数据类型。

  • 它的值是唯一的,用来解决命名冲突的问题
  • 不能与其他数据做运算
  • 不能使用for遍历,但是可以使用Reflect.ownKeys来获取对象的所有健名
// 创建Symbol
let s = Symbol() // Symbol()
let s2 = Symbol('嘿嘿')
let s3 = Symbol('嘿嘿')
console.log(s2 === s3)  //false
let s4 = Symbol.for('嘿嘿')
let s5 = Symbol.for('嘿嘿')
console.log(s4 === s5)  //true
迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。

  1. Es6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费

  2. 原生具备Iterator接口的数据(可用for of遍历)
    Array
    Arguments
    Set
    Map
    String
    TypedArray
    NodeList

  3. 工作原理
    a) 创建一个指针对象,指向当前数据结构的起始位置。
    b) 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    c) 接下来不断的调用next方法,指针一直往后移动,直到指向最后一个成员
    d) 每调用next方法返回一个包含value和done属性的对象

  4. 注:需要自定义遍历数据的时候,要想到迭代器

// 声明一个数组
const xiyou = [ '唐僧','孙悟空','猪八戒','沙僧' ]
for(let v of xiyou){
	console.log(v);
}

let iterator = xiyou[Symbol.iterator]();

// 调用对象的next方法
console.log(iterator.next()) // {value: '唐僧', done: false}
console.log(iterator.next()) // {value: '孙悟空', done: false}
console.log(iterator.next()) // {value: '猪八戒', done: false}
console.log(iterator.next()) // {value: '沙僧', done: false}
console.log(iterator.next()) // {value: undefined, done: true}
// 自定义遍历数据
const banji = {
	name:"终极一班",
	stus:[
		'小王',
		'小张',
		'小陈'
	],
	[Symbol.iterator](){
		let index = 0
		let _this = this
		return {
			next:function(){
				if(index < this.stus.length){
					const result = { value:_this.stus[i],done:false}
					index++
					return result
				}else{
					return { value:undefined,done:true}
			}
		}
	}
}
生成器

生成器其实就是一个特殊的函数

function * gen(){
	console.log('111')
	yield '一只没有耳朵'; // 函数代码的分隔符
	console.log('222')
	yield '一只没有尾部';
	console.log('333')
	yield '真奇怪';
	console.log('444')
}
let iterator = gen();
iterator.next(); // 111
iterator.next(); // 222
iterator.next(); // 333
iterator.next(); // 444
function * gen(){
	yield '一只没有耳朵'; // 函数代码的分隔符
	yield '一只没有尾部';
	yield '真奇怪';
}
let iterator = gen();
console.log(iterator.next()); // {value: '一只没有耳朵', done: false}
console.log(iterator.next()); // {value: '一只没有尾部', done: false}
console.log(iterator.next()); // {value: '真奇怪', done: false}
console.log(iterator.next()); // {value: undefined, done: true}


// 遍历
for(let v of gen()){
	console.log(v);
}
// 一只没有耳朵
// 一只没有尾部
// 真奇怪

生成器函数参数

function * gen(arg){
	console.log(arg);
	let one = yield 111; // 函数代码的分隔符
	console.log(one);
	let two = yield 222;
	console.log(two);
	let three = yield 333;
	console.log(three);
}
let iterator = gen('aaa'); // 无打印结果
console.log(iterator.next());  //aaa  {value: '111', done: false}
console.log(iterator.next('bbb'));  //bbb  {value: '222', done: false}
console.log(iterator.next('ccc'));  //ccc {value: '333', done: false}
console.log(iterator.next('ddd'));  //ddd {value: undefined, done: true}

生成器函数实例

function one(){
	setTimeout(()=>{
		console.log(111)
		iterator.next();
	},1000)
}
function two(){
	setTimeout(()=>{
		console.log(222)
		iterator.next();
	},2000)
}
function three(){
	setTimeout(()=>{
		console.log(333)
		iterator.next();
	},3000)
}
function * gen(){
	yield one(); // 函数代码的分隔符
	yield two();
	yield three();
}
let iterator = gen(); // 无打印结果
iterator.next();
// 111
// 222
// 333
function getUsers(){
	setTimeout(()=>{
		let data = '用户数据'
		// 调用next方法,并且将数据传入
		iterator.next(data);
	},1000)
}
function getOrders(){
	setTimeout(()=>{
		let data = '订单数据'
		iterator.next(data);
	},2000)
}
function getGoods(){
	setTimeout(()=>{
		let data = '商品数据'
		iterator.next(data);
	},3000)
}
function * gen(){
	let users = yield getUsers(); // 函数代码的分隔符
	console.log(users)
	let orders = yield getOrders();
	console.log(orders)
	let goods = yield getGoods();
	console.log(goods)
}
let iterator = gen(); // 无打印结果
iterator.next();
// 用户数据
// 订单数据
// 商品数据
Promise

Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作可以获取其成功或失败的结果。

// 实例化Promise对象
const p = new Promise(function(resolve,reject){
	setTimeout(function(){
		// let data = '数据库中的数据'
		// resolve(data)
		let err = '数据读取失败'
		reject(err)
	},1000);
})

// 调用 promise对象的then方法
p.then(function(value){
	console.log(value);
},function(reason){
	console.error(reason);
})

Promise封装读取文件

const fs = require('fs');

const p = new Promise(function(resolve,reject){
	fs.readFile("./resources/为学.mda",(err,data)=>{
		// 判断如果失败
		if(err) reject(err);
		//如果成功
		resolve(data);
	})
})

p.then(function(value){
	console.log(value.toString());
},function(reason){
	console.log("读取失败!")
})

Promise封装AJAX

const p = New Promise((resolve,reject) => {
	// 创建对象
	const xhr = new XMLHttpRequest();
	// 初始化
	xhr.open("GET","https://api.apiopen.top/getJosn");
	// 发送
	xhr.send();
	// 绑定事件,处理响应结果
	xhr.onreadystatechange = function(){
		if(xhr.readyState === 4){
			if(xhr.status >= 200 && xhr.status < 300) {
				resolve(xhr.response);
			}else{
				reject(xhr.status)
			}
		}
	}
})

p.then(function(value){
	console.log(value)
},function(reason){
	console.error(reason)
})

Promise.prototype.then 方法

// 创建一个Promise对象
const p = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve('用户数据');
	},1000)
})
// 调用then方法 then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定 
// 1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象成功的值
// 2.如果回调函数中返回的结果是promise类型的属性,状态为成功,返回值为对象成功的值,失败即失败的值
const result = p.then(value => {
	console.log(value)
	// 1. 非promise 对象
	// return '231'
	// 2. promise 对象
	// return new Promise((resolve,reject)=>{
	// 	// resolve('ok');
	// 	reject('error');
	// })
	// 3.抛出错误
	throw ('出错啦!');
}, reason => {
	console.warn(reason)
})
// 
console.log(result);

// 链式调用
p.then(value=>{

}).then(value=>{

})

catch方法

const p = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject("出错啦!")
	},1000)
})
p.catch(function(reason)=>{
	console.err(reason)
})
set集合

ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for…of… 进行遍历。
集合的属性和方法

  1. size 返回集合元素的个数
  2. add 增加一个新元素,返回当前集合
  3. delete 删除元素,返回boolean值
  4. has 检测集合十分包含某个元素,返回boolean值
let arr = [1,2,3,4,5,6,7,4,3,4,2,1]
// 1.数组去重
let result = [...new Set(arr)];
// 2.交集
let arr2 = [2,4,6,8,9,3]
let result = [...new Set(arr)].filter(item =>{
	let s2 = new Set(arr2);
	if(s2.has(item)){
		return true
	}else{
		return false
	}
})
// let result = [...new Set(arr)].filter(item => new Set(arr2).has(item)); 
//cosole.log(result)

//  并集
let union = [...new Set([...arr,...arr2])];

// 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item))); 
Map

ES6提供了Map数据结构,它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用扩展运算符和for…of…进行遍历。
Map的属性和方法

  1. size 返回Map的元素的个数
  2. set 增加一个新元素,返回当前Map
  3. get 返回键名对象的键值
  4. has 检测Map中是否包含某个元素,返回boolean值
  5. clear 清空集合,返回undefined
// 声明 Map 
let m = new Map();
// 添加元素
m.set('name','张三') // Map(1) {'name' => '张三'}
m.set('change',function(){console.log('我们可以改变你')}) // {'name' => '张三', 'change' => ƒ}
let key = { school: '123'}
m.set(key,[1,2,3]) // Map(3) {'name' => '张三', 'change' => ƒ, {…} => Array(3)}
// 删除
m.delete('name') // Map(2) {'change' => ƒ, {…} => Array(3)}
// 遍历
for(let v of m){
	console.log(v);
}
// (2) ['change', ƒ]
// (2) [{…}, Array(3)]

// 清空
m.clear()
类 class
// ES5 通过实例化函数

function Phone (brand,price){
	this.brand = brand;
	this.price = price;
}
// 添加方法
Phone.prototype.call = function(){
	console.log('我可以打电话!')
}

// 实例化对象
let Huawei = new Phone('华为',5999)
Huawei.call(); // 我可以打电话!
console.log(Huawei) // Phone {brand: '华为', price: 5999}
// ES6
class Phone {
	constructor(brand,price){
		this.brand = brand;
		this.price = price;
	}
	call(){
		console.log('我可以打电话!')
	}
}

let onePuls = new Phone("1+",1999);
console.log(onePuls)  // Phone {brand: '1+', price: 1999}

class 静态成员

function Phone(){}
// 静态成员 是属于函数对象的并不属于实例对象
Phone.name = '手机';
Phone.change = function(){
	console.log('我可以改变世界')
}
let nokia = new Phone();
console.log(nokia.name); // undefined
nokia.change();// 报错
Phone.prototype.size = '5.5inch' // 放在原型链上的 
console.log(nokia.size); // 5.5inch
class Phone{
	// 静态属性 属于类而不属于实例对象
	static name = "手机";
	static change(){
		console.log('我可以改变世界')
	}
}
let nokia  = new Phone();
console.log(nokia.name) // undefined
console.log(Phone.name) // 手机

ES5构造函数继承

// 手机
function Phone(brand,price){
	this.brand = brand;
	this.price = price;
}
Phone.prototype.call = function(){
	console.log('我可以打电话!')
}
function SmartPhone(brand,price,color,size){
	Phone.call(this,brand,price);
	this.color = color;
	this.size = size;
}
SmartPhone.prototype = new Phone;
SmartPhone.prototype.photo = function(){
	console.log("我可以拍照")
}
SmartPhone.prototype.playGame= function(){
	console.log("我可以玩游戏")
}
const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch')
console.log(chuizi)

ES6 class类的继承

class Phone {
	constructor(brand,price){
		this.brand = brand;
		this.price = price;
	}
	call(){
		cosole.log('我可以打电话!')
	}
}

class SmartPhone extends Phone {
	constructor(brand,price,color,size){
		super(brand,price);
		this.color= color;
		this.size= size;
	}
	photo(){
		console.log('我可以拍照')
	}
	playGame(){
		console.log('玩游戏')
	}
	// 子类重写父类方法
	call(){
		cosole.log('我可以视频通话!')
	}
}

const xiaomi = new SmartPhone('小米',799,'黑色','5.5')
console.log(xiaomi) // SmartPhone {brand: '小米', price: 799, color: '黑色', size: '5.5'}

class类中的getter 和setter
class Phone{
	get price(){
		console.log('价格被读取了')
	}
	set price(newVal){
		console.log('价格被修改了')
	}
}

let a = new Phone
console.log(a.price) // 价格被读取了
a.price = 'free'  // 价格被修改了
数值的扩展

Number.EPSILON 是JavaScript 表示的最小精度

function equal(a,b){
	if(Math.abs(a-b) < Number.EPSILON){
		return true;
	}else{
		return false
	}
}
console.log(0.1+0.2===0.3) // false
console.log(equal(0.1+0.2,0.3)) // true

二进制和八进制,十进制,十六进制

let b = 0b1010; // 10
let o = 0o777; // 511
let d = 100; // 100
let x = 0xff; // 255

Number.isFinite 检测一个数值是否为有限数

console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(100/0)); // false
console.log(Number.isFinite(Infinity)); // false

Number.isNaN 检测一个数值是否为NaN,是否为非数字

console.log(Number.isNaN(123)) // false

Number.parseInt Number.parseFloat 字符串转整数

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

Number.isInteger 判断一个数是否为整数

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

Math.trunc 将数字的小数部分抹掉

console.log(Math.trunc(3.5));  // 3

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

console.log(Math.sign(100)); //1
console.log(Math.sign(0)); //0
console.log(Math.sign(-100)); //-1
对象方法的扩展
// Object.is   判断两个值是否完全相等
console.log(Object.is(120,120)); // true
console.log(Object.is(NaN,NaN)); // true

// Object.assign 对象的合并
const config1 = {
	host: 'localhost',
	port: 3306,
	name: 'root',
	pass: 'root'
}
const config2 = {
	host: 'http://atguigu.com',
	port: 33060,
	name: '张三',
	pass: 'iloveyou'
}
console.log(Object.assign(config1,config2)); // {host: 'http://atguigu.com', port: 33060, name: '张三', pass: 'iloveyou'}      后面那个对象属性会覆盖前面已有的对象属性

 // 设置原型对象 Object.setPrototypeOf   获取原型对象 Object.getPrototypeOf
 const school = {
	name:'尚硅谷'
}
const cities = {
	xiaoqu: ['北京','上海','深圳']
}

Object.setPrototypeOf(school,cities);
console.log(school);
//{name: '尚硅谷'}
//	name: "尚硅谷"
//		[[Prototype]]: Object
//			xiaoqu: (3) ['北京', '上海', '深圳']
//			[[Prototype]]: Object
console.log(Object.getPrototypeOf(school))
//{xiaoqu: Array(3)}
//	xiaoqu: (3) ['北京', '上海', '深圳']
//	[[Prototype]]: Object
模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

模块化的好处

模块化的优势

  • 防止命名冲突
  • 代码复用性高
  • 高维护性
模块化规划产品

ES6之前的模块化规范有

  • CommonJS => NodeJS、 Browserify
  • AMD => requireJS
  • CMD => seaJS
ES6 模块化语法

模块功能主要由两个命令构成:export和import

  • export 命令用于规定模块的对外接口
  • import命令用于输入其他模块提供的功能
// m1.js 分别暴露
export let school = '大学'
export function teach(){
	console.log("我们可以教你开发技能!")
} 
// m2.js 统一暴露
let school = '大学'
function teach(){
	console.log("我们可以教你开发技能!")
} 
export{school,findJob};

// m3.js 默认暴露
export default {
	let school = '大学'
	function teach(){
		console.log("我们可以教你开发技能!")
	} 
}
// index.html

// 通用的导入方式
// 引入m1.js 模块内容
import * as m1 from "./src/js/m1.js";
// 引入m2.js 模块内容
import * as m2 from "./src/js/m2.js";
// 引入m3.js 模块内容
import * as m3 from "./src/js/m3.js";
m3.default.change(); // 我们可以教你开发技能!

// 结构赋值的形式
import {school,teach} from "./src/js/m1.js"
import {school as guigu} from "./src/js/m2.js" // as guigu   别名
import {default as m3} from "./src/js/m3.js"

// 简便形式 针对默认暴露
import m3 from "./src/js/m3.js"

ES7新特性

Array.prototype.includes
用来检测数组中是否包含某个元素,返回布尔类型值
指数操作符
用来实现幂运算,功能与Math.pow结果相同

// includes    indexOf(查找索引)
const mingzhu= ['西游记','三国演义','红楼梦','水浒传'];

// 判断
console.log(mingzhu.includes('西游记')); // true

// **
console.log(2 ** 10); // Math.pow(2,10) // 1024 2的10次方

ES8

async和await

async和await两种语法结合可以让异步代码像同步代码一样

async

  1. 返回值为promise对象
  2. promise对象的结果由async函数执行的返回值决定
async function fn(){
	return '嗯嗯' // 返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象
	// 抛出错误 ,返回的结果是一个失败的Promise
	// throw new Error('出错啦!')
}
const result = fn();
console.log(result)
//Promise {<fulfilled>: '嗯嗯'}
//	[[Prototype]]: Promise
//	[[PromiseState]]: "fulfilled"
//	[[PromiseResult]]: "嗯嗯"

await

  1. await必须卸载async函数中
  2. await右侧的表达式一般为promise对象
  3. await返回的是promise成功的值
  4. await的promise失败了。就会抛出异常,需要通过try…catch捕获处理
const p = new Promise((resolve,reject)=>{
	resolve('成功的值!')
})
async function main(){
	let result = await p;
	console.log(result);
}

//
main(); //成功的值!
const p = new Promise((resolve,reject)=>{
	reject('失败啦')
})
async function main(){
	try{
		let result = await p;
		console.log(result);
	}catch (e){
		console.log(e)
	}
}

//
main(); //失败啦!
async与await结合发送AJAX请求
function sendAJAX(url) {
	return new Promise((resolve,reject) => {
		// 创建对象
		const x = new XMLHttpRequest();
		// 初始化
		x.open('GET',url);
		// 发送
		x.send();
		// 事件绑定
		x.onreadystatechange = function () {
			if(x.readyState === 4) {
				if(x.status >= 200 && x.status <300) {
					// 成功啦
					resolve(x.response);
				}else{
					// 如果失败
					reject(x.status)
				}
			}
		}
	})
}

sendAJAX('https://api/getJoke').then(value=>{
	console.log(value)
},reason=>{
	console.log(reason)
})

// async 与await测试
async function main(){
	let result = await sendAJAX("https://api/getJoke");
	console.log(result);
}
main()
ES8对象方法扩展
// 声明对象
const school = {
	name: "张三",
	cities:['重庆','上海','深圳'],
	xueke: ['前端','java','大数据','运维']
};
// 获取对象所有的键
console.log(Object.keys(school))// ['name', 'cities', 'xueke']
console.log(Object.values(school))// ['张三', Array(3), Array(4)]
console.log(Object.entries(school))
//0: (2) ['name', '张三']
//1: (2) ['cities', Array(3)]
//2: (2) ['xueke', Array(4)]

// 创建 Map 
const m = new Map(Object.entries(school));
console.log(m.get('cities')); // ['重庆', '上海', '深圳']
// 对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
const obj = Object.create(null,{
	name:{
		value:'你好',// 设置值
		writable:true,//是否可写
		configurable:true,//是否可以删除
		enumerable:true//是否可以枚举
	}
})

ES9 正则扩展-命名捕获分组
// 声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// 提取url 与标签文本
const reg = /<a href="(.*)">(.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
// ['<a href="http://www.atguigu.com">尚硅谷</a>', 'http://www.atguigu.com', '尚硅谷', index: 0, input: '<a href="http://www.atguigu.com">尚硅谷</a>', groups: undefined]

// 声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// 提取url 与标签文本
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
//0: "<a href=\"http://www.atguigu.com\">尚硅谷</a>"
//1: "http://www.atguigu.com"
//2: "尚硅谷"
//groups: {url: 'http://www.atguigu.com', text: '尚硅谷'}
//index: 0
//input: "<a href=\"http://www.atguigu.com\">尚硅谷</a>"
正则扩展 -反向断言
let str = 'js283773你回到789啦啦啦';
// 正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result);
//['789', index: 11, input: 'js283773你回到789啦啦啦', groups: undefined]
//0: "789"
//groups: undefined
//index: 11
//input: "js283773你回到789啦啦啦"
//length: 1

// 反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result)
//['789', index: 11, input: 'js283773你回到789啦啦啦', groups: undefined]
//0: "789"
//groups: undefined
//index: 11
//input: "js283773你回到789啦啦啦"
//length: 1
ES10 - 对象的扩展方法
// Object.entries的逆向操作 es8
//二维数组 
const result = Object.fromEntries([
	['name','尚硅谷'],
	['xueke','java,大数据,前端']
]);
console.log(result) //{name: '尚硅谷', xueke: 'java,大数据,前端'}

trimStart 与trimEnd

删除字符串前面或者后面的空格

let str = '   abc    '
str.trimStart() //'abc    '
str.trimEnd() //'abc'
flat和flatMap

flat,将多维数组转换为低位数组

let arr = [1,2,3,4,[5,6]]
console.log(arr.flat()) //  [1, 2, 3, 4, 5, 6]
let arr1 = [1,2,3,4,[5,6,[7,8,9]]]
console.log(arr1.flat()) //  [1, 2, 3, 4, 5, 6, Array(3)]
console.log(arr1.flat(2)) //  [1, 2, 3, 4, 5, 6, 7, 8, 9]  深度为2 打开两层
// flatMap 相当于是flat和map 的结合
let arr2 = [1,2,3,4]
let result = arr2.flatMap(item => [item * 10]);
console.log(result) //[10, 20, 30, 40]
Symbol.prototype.description
let s = Symbol('尚硅谷');

console.log(s.description) //尚硅谷
ES11 私有属性
class Person{
	// 公有属性
	name;
	// 私有属性
	#age;
	#weight;
	// 构造方法
	constrctor(name,age,weight){
		this.name = name;
		this.#age = age;
		this.#weight = weight;
	}
	intro(){
		console.log(this.name);
		console.log(this.#age);
		console.log(this.#weight);
	}
}
// 实例化
const girl = new Person('小红',18,'45kg');
console.log(girl); // {name: undefined, #age: undefined, #weight: undefined}
console.log(girl.#age); // 报错 只能出现在类里面,不能出现在类外面
intro()
// 小红
// 18
// 45kg
Promise.allSettled
const p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve('商品数据1')
	},1000)
})

const p2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject('出错啦')
	},1000)
})
const result = Promise.allSettled([p1,p2]);// allSettled两个Promise对象返回值一个是resolve就返回成功
console.log(result)
// Promise {<pending>}
//	[[Prototype]]: Promise
//	[[PromiseState]]: "fulfilled"
//	[[PromiseResult]]: Array(2)
//		0: {status: 'fulfilled', value: '商品数据1'}
//		1: {status: 'rejected', reason: '出错啦'}
//		length: 2
//		[[Prototype]]: Array(0)

```javascript
const p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve('商品数据1')
	},1000)
})

const p2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject('出错啦')
	},1000)
})
const res = Promise.all([p1,p2]); // all两个Promise对象返回值都必须是resolve才返回成功
console.log(res)
//Promise {<pending>}
//	[[Prototype]]: Promise
//	[[PromiseState]]: "rejected"
//	[[PromiseResult]]: "出错啦"

可选链操作符
function main(config){
	const dbHost = config?.db?.host; // config有 找到config.db,确认有,找到config.db.host
	console.log(dbHost);
}
main({
	db:{
		host:'192.168.1.100',
		username:'root'
	},
	cache:{
		host:'192.168.1.100',
		username:'root'
	}
})
动态import

按需引入

// import * as m1 from "./hello.js"; //静态引入
const btn = document.getElementById('btn');
btn.onclick = function(){
	import('./hello.js').then(module => { //动态引入,按需加载
		module.hello();
	})
}
BigInt
//大整形
let n = 521n;
console.log(n,typeof(n)); //521n 'bigint'
// 函数
let n = 123;
console.log(BigInt(n));
console.log(BigInt(1.2));

// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);//9007199254740991
console.log(max + 1);//9007199254740992
console.log(BigInt(max) + 1);//报错
console.log(BigInt(max) + BigInt(1));//9007199254740992
globalThis

无论什么环境下指向全局对象

console.log(globalThis)//Window {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值