1、let 关键字
特性: let 关键字用来声明变量,使用 let 声明的变量有几个特点:
1. 不允许重复声明;
2. 块儿级作用域(局部变量);
3. 不存在变量提升;
4. 不影响作用域链;
应用场景:
以后声明变量使用 let 就对了;
<script>
// 获取div元素对象
let items = document.getElementsByClassName('item');
// 遍历并绑定事件
for (let i = 0; i < items.length; i++) {
items[i].onclick = function () {
// 修改当前元素的背景颜色
// this.style.background = 'pink'; // 写法一:常规写法一般无异常
items[i].style.background = 'pink'; // 写法二
// 写法二:需要注意的是for循环内的i必须使用let声明
// 如果使用var就会报错,因为var是全局变量,
// 经过循环之后i的值会变成3,items[i]就会下标越界
// let是局部变量
// 我们要明白的是当我们点击的时候,这个i是哪个值
// 使用var相当于是:
// { var i = 0; }
// { var i = 1; }
// { var i = 2; }
// { var i = 3; }
// 下面的声明会将上面的覆盖掉,所以点击事件每次找到的都是3
// 而使用let相当于是:
// { let i = 0; }
// { let i = 1; }
// { let i = 2; }
// { let i = 3; }
// 由于let声明的是局部变量,每一个保持着原来的值
// 点击事件调用的时候拿到的是对应的i
}
}
</script>
外层for循环只是给每个item绑定了点击事件,然后点击事件是异步任务,for已经执行完了.
这里先循环把每个div添加上了事件,循环结束后i已经变成3了.
click是异步任务,执行时i的值是已经循环完的值了.
2、const 关键字
保存的地址,地址没有变化。
3、变量和对象的解构赋值
4、模板字符串
概述: 模板字符串(template string)是增强版的字符串,用反引号(`)标识,
特点: 字符串中可以出现换行符; 可以使用 ${xxx} 形式引用变量;
// 定义字符串
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
// 变量拼接
let star = '王宁';
let result = `${star}在前几年离开了开心麻花`;
5、简化对象和函数写法
概述: ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;
let name = '尚硅谷';
let slogon = '永远追求行业更高标准';
let improve = function () {
console.log('可以提高你的技能');
}
//属性和方法简写
let atguigu = {
name,
slogon,
improve,
change() {
console.log('可以改变你')
}
};
6、箭头函数
概述:
ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿 名函数的定义;
箭头函数的注意点:
1. 如果形参只有一个,则小括号可以省略;
2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果;
3. 箭头函数 this 指向声明时所在作用域下 this 的值;
4. 箭头函数不能作为构造函数实例化;
5. 不能使用 arguments;
特性:
1. 箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值;
2. 不能作为构造函数,不能作为构造实例化对象;
3. 不能使用 arguments 变量;
箭头函数的this会继承父执行上下文里面的this
注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适;
<script>
// ES6 允许使用「箭头」(=>)定义函数。
//声明一个函数
// let fn = function(){
// }
// let fn = (a,b) => {
// return a + b;
// }
//调用函数
// let result = fn(1, 2);
// console.log(result);
//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
function getName(){
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
//设置 window 对象的 name 属性
window.name = '尚硅谷';
const school = {
name: "ATGUIGU"
}
//直接调用
// getName();
// getName2();
//call 方法调用
// getName.call(school);
// getName2.call(school);
//2. 不能作为构造实例化对象
// let Person = (name, age) => {
// this.name = name;
// this.age = age;
// }
// let me = new Person('xiao',30);
// console.log(me);
//3. 不能使用 arguments 变量
// let fn = () => {
// console.log(arguments);
// }
// fn(1,2,3);
//4. 箭头函数的简写
//1) 省略小括号, 当形参有且只有一个的时候
// let add = n => {
// return n + n;
// }
// console.log(add(9));
//2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
// 而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(8));
</script>
需求-1:点击 div 2s 后颜色变成『粉色』:
JavaScript 内置函数的回调函数 this 一般都指向 window,箭头函数因为没有自己的this,找到外部的普通函数的 this ,也就是 ad (普通函数被 ad 调用)
//需求-1 点击 div 2s 后颜色变成『粉色』
//获取元素
let ad = document.getElementById('ad');
//绑定事件
ad.addEventListener("click", function(){
//保存 this 的值
//_this 表示外部调用监听事件的元素本身,而setTimeout方法内部的this仍然是指向window
///JavaScript 内置函数的回调函数 this 一般都指向 window,箭头函数因为没有自己的this,
//找到外部的普通函数的 this ,也就是 ad (普通函数被 ad 调用)
// let _this = this;
//定时器
setTimeout(() => {
//修改背景颜色 this
// console.log(this);
// _this.style.background = 'pink';
this.style.background = 'pink';
}, 2000);
});
需求-2 从数组中返回偶数的元素:
//需求-2 从数组中返回偶数的元素
const arr = [1,6,9,10,100,25];
//filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表,
//接收两个参数,一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断
//filter() 函数用于过滤序列序列的每个元素作为参数传递给函数进行判断,
//然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
// const result = arr.filter(function(item){
// if(item % 2 === 0){
// return true;
// }else{
// return false;
// }
// });
const result = arr.filter(item => item % 2 === 0);
console.log(result);
// 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
// 箭头函数不适合与 this 有关的回调. 事件回调,(绑定的事件的回调,不再指向事件源,而是外层执行上下文的this) 对象的方法
let a = {
b:{
c:function(){
console.log(this);
},
e:()=>{
console.log(this);
}
},
d:function(){
console.log(this);
}
}
a.b.c(); //c
//在函数作为对象的属性情况下,function函数和箭头函数中的this指向不相同。箭头函数中的this并没有指向调用该函数的对象,而是指向window。
a.b.e(); //window
a.d(); //a
7、ES6中函数参数的默认值
概述: ES允许给函数的参数赋初始值;
<script>
//ES6 允许给函数参数赋值初始值
//1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
// function add(a,c=10,b) {
// return a + b + c;
// }
// let result = add(1,2);
// console.log(result);
//2. 与解构赋值结合
//host默认值,没有传入host参数,则用默认值
function connect({host="127.0.0.1", username,password, port}){
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306
})
</script>
8、rest参数
概述: ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
<script>
//ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
//ES5 获取实参的方式
function date(){
console.log(arguments);//是一个对象
}
date('白芷','阿娇','思慧');
///rest 参数
function datee(...args){
console.log(args);//是一个数组 可以使用数组的方法 filter some every map
}
datee('阿娇','柏芝','思慧');
//rest 参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);//1
console.log(b);//2
console.log(args);//3,4,5,6
}
fn(1,2,3,4,5,6);
</script>
9、扩展运算符
介绍:
『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
... 扩展运算符能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(...)。
它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参 数序列,对数组进行解包;
<script>
// 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
//声明一个数组 ...
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'
// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(tfboys)
chunwan(...tfboys);//相当于 chunwan('易烊千玺','王源','王俊凯')
</script>
应用:
<div></div>
<div></div>
<div></div>
<script>
//1. 数组的合并 情圣 误杀 唐探
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
//扩展运算符可以把数组转为逗号分割的参数序列
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);
//2. 数组的克隆
const sanzhihua = ['E','G','M'];
//浅拷贝:就是拷贝变量所存的值,如果是引用变量,那拷贝的就是它里面的地址
const sanyecao = [...sanzhihua];// ['E','G','M']
console.log(sanyecao);
//3. 将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);// arguments
</script>
divs是一个对象
divArr
10、Symbol
概述: ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类 型,是一种类似于字符串的数据类型;
特点:
1. Symbol 的值是唯一的,用来解决命名冲突的问题;
2. Symbol 值不能与其他数据进行运算;
3. Symbol 定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的 所有键名;
<script>
//创建Symbol
//Symbol作为一个函数
let s = Symbol();
// console.log(s, typeof s);
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
//Symbol.for 创建
//Symbol作为一个对象
let s4 = Symbol.for('尚硅谷');
let s5 = Symbol.for('尚硅谷');
//不能与其他数据进行运算
// let result = s + 100;
// let result = s > 100;
// let result = s + s;
// USONB
// you are so niubility
// u undefined
// s string symbol
// o object
// n null number
// b boolean
</script>
Symbol创建对象属性:
<script>
//向对象中添加方法 up down
let game = {
name:'俄罗斯方块',
up: function(){},
down: function(){}
};
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function(){
console.log("我可以改变形状");
}
game[methods.down] = function(){
console.log("我可以快速下降!!");
}
console.log(game);
let youxi = {
name:"狼人杀",
[Symbol('say')]: function(){
console.log("我可以发言")
},
[Symbol('zibao')]: function(){
console.log('我可以自爆');
}
}
console.log(youxi)
</script>
Symbol内置值:
概述:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方 法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;
方法:
<script>
class Person{
static [Symbol.hasInstance](param){
console.log(param);//o
console.log("我被用来检测类型了");
//return false;
}
}
let o = {};
console.log(o instanceof Person);//false
const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
</script>
11、迭代器
for...in 返回的是字符串。
for...of
概述:
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数 据结构只要部署 Iterator 接口,就可以完成遍历操作;
特性:
ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费;
原生具备 iterator 接口的数据(可用 for of 遍历):
Array; Arguments; Set; Map; String; TypedArray; NodeList;
工作原理:
1. 创建一个指针对象,指向当前数据结构的起始位置;
2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;
注:需要自定义遍历数据的时候,要想到迭代器;
<script>
//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
///使用 for...of 遍历数组
for(let v of xiyou){
console.log(v);
}
console.log(xiyou)
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
</script>
迭代器自定义遍历对象:
<script>
//声明一个对象
const banji = {
name: "终极一班",
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator]() {
//索引变量
let index = 0;
//
let _this = this;
return {
next: function () {
if (index < _this.stus.length) {
const result = { value: _this.stus[index], done: false };
//下标自增
index++;
//返回结果
return result;
}else{
return {value: undefined, done: true};
}
}
};
}
}
//遍历这个对象
for (let v of banji) {
console.log(v);
}
</script>
12、生成器
概述: 生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
<script>
//生成器其实就是一个特殊的函数
//异步编程 纯回调函数 node fs ajax mongodb
//函数代码的分隔符
function * gen(){
// console.log(111);
yield '一只没有耳朵';
// console.log(222);
yield '一只没有尾部';
// console.log(333);
yield '真奇怪';
// console.log(444);
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
//遍历
// for(let v of gen()){
// console.log(v);
// }
</script>
生成器函数的参数传递:
<script>
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());
//next方法可以传入实参
//参数作为传入的参数作为第一条(上一条)语句yield 111的返回结果
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));
</script>
生成器函数实例1:
<script>
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作
// 1s 后控制台输出 111 2s后输出 222 3s后输出 333
// 回调地狱
// setTimeout(() => {
// console.log(111);
// setTimeout(() => {
// console.log(222);
// setTimeout(() => {
// console.log(333);
// }, 3000);
// }, 2000);
// }, 1000);
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();
</script>
生成器函数实例2:
<script>
//模拟获取 用户数据 订单数据 商品数据
function getUsers(){
setTimeout(()=>{
let data = '用户数据';
//调用 next 方法, 并且将数据传入
//next方法可以传入实参
//参数作为传入的参数作为第一条(上一条)语句yield getUsers()的返回结果
//第二次调用next
iterator.next(data);
}, 1000);
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据';
iterator.next(data);
}, 1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据';
iterator.next(data);
}, 1000)
}
function * gen(){
let users = yield getUsers();
//对数据进行操作
console.log(users)
let orders = yield getOrders();
let goods = yield getGoods();
}
//调用生成器函数
let iterator = gen();
iterator.next();
</script>
13、Promise
概述:
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作 并可以获取其成功或失败的结果;
1. Promise 构造函数: Promise (excutor) {};
2. Promise.prototype.then 方法;
3. Promise.prototype.catch 方法;
<script>
//实例化 Promise 对象
//接收一个函数作为参数
const p = new Promise(function(resolve, reject){
setTimeout(function(){
//
// let data = '数据库中的用户数据';
// resolve p对象状态变为成功
//调用then方法的第一 个回调函数
// resolve(data);
//p对象状态变为成功
//调用then方法的第二个回调函数
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用 promise 对象的 then 方法
//接收两个函数作为参数
//value 成功
//reason 失败吧
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
})
</script>
Promise封装读取文件:
//1. 引入 fs 模块
const fs = require('fs');
//2. 调用方法读取文件
//第一个参数为文件地址,第二个 参数为回调函数
fs.readFile('./resources/为学.md', (err, data)=>{
//如果失败, 则抛出错误
if(err) throw err;
//如果没有出错, 则输出内容
console.log(data.toString());
});
//3. 使用 Promise 封装
const p = new Promise(function(resolve, reject){
fs.readFile("./resources/为学.mda", (err, data)=>{
//判断如果失败
if(err) reject(err);
//如果成功
//resolve函数修改p状态为成功
//参数设置成功的值
resolve(data);
});
});
p.then(function(value){
//value是一个bufferr
console.log(value.toString());
}, function(reason){
console.log("读取失败!!");
});
原始Ajax请求
<script>
// 请求地址:https://api.apiopen.top/getJoke
// 原生请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open("GET", "https://api.apiopen.top/getJoke");
// 3、发送
xhr.send();
// 4、绑定事件,处理响应结果
xhr.onreadystatechange = function () {
// 判断状态
if (xhr.readyState == 4) {
// 判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status <= 299) {
// 成功
console.log(xhr.response);
} else {
// 失败
console.error(xhr.status);
}
}
}
</script>
Promise封装Ajax请求:
<script>
// 接口地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJoke");
//3. 发送
xhr.send();
//4. 绑定事件, 处理响应结果
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
//判断响应状态码 200-299
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);
});
</script>
Promise.prototype.then:
then 方法的返回值也是一个Promise对象
对象状态由回调函数的执行结果决定。
//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
不写return则 undefined为成功值
return一个promise
抛出错误
<script>
//创建 promise 对象
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('用户数据');
// reject('出错啦');
}, 1000)
});
//调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
// const result = p.then(value => {
// console.log(value);
// //1. 非 promise 类型的属性
// // return 'iloveyou';
// //2. 是 promise 对象
// // return new Promise((resolve, reject)=>{
// // // resolve('ok');
// // reject('error');
// // });
// //3. 抛出错误
// // throw new Error('出错啦!');
// throw '出错啦!';
// }, reason=>{
// console.warn(reason);
// });
//链式调用
//是从前往后,一个调用成功后return出下一个promise对象,以此类推
p.then(value=>{
}).then(value=>{
});
</script>
Promise实践练习:
“回调地狱”方式写法:
//引入 fs 模块
const fs = require("fs");
fs.readFile('./resources/为学.md', (err, data1)=>{
fs.readFile('./resources/插秧诗.md', (err, data2)=>{
fs.readFile('./resources/观书有感.md', (err, data3)=>{
let result = data1 + '\r\n' +data2 +'\r\n'+ data3;
console.log(result);
});
});
});
Promise实现:
//使用 promise 实现
const p = new Promise((resolve, reject) => {
fs.readFile("./resources/为学.md", (err, data) => {
//如果成功
//resolve函数修改p状态为成功
//参数设置成功的值,是该文件内容
resolve(data);
});
});
//value是第一个文件内容
p.then(value => {
//返回一个promise对象
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧诗.md", (err, data) => {
//此次成功p.then返回的promise也是成功的,此次成功的值就是p.then返回的promise成功的值
resolve([value, data]);
});
});
//此次的value就是[value, data]
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./resources/观书有感.md", (err, data) => {
//压入
value.push(data);
//此次成功.then返回的promise也是成功的,此次成功的值就是.then返回的promise成功的值
resolve(value);
});
})
//value就是三个文件的内容
}).then(value => {
console.log(value.join('\r\n'));
});
Promise对象catch方法:
<script>
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
//设置 p 对象的状态为失败, 并设置失败的值为"出错啦!"
reject("出错啦!");
}, 1000)
});
// p.then(function(value){}, function(reason){
// console.error(reason);
// });
p.catch(function(reason){
console.warn(reason);
});
</script>
14、Set集合
概述: ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法: 1. size 返回集合的元素个数;
2. add 增加一个新元素,返回当前集合;
3. delete 删除元素,返回 boolean 值;
4. has 检测集合中是否包含某个元素,返回 boolean 值;
5. clear 清空集合,返回 undefined;
<script>
//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
//元素个数
console.log(s2.size);
//添加新的元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿');
//检测
console.log(s2.has('糟心事'));
//清空
s2.clear();
console.log(s2);
for(let v of s2){
console.log(v);
}
</script>
Set集合实践:
<script>
let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
//扩展运算符
let result = [...new Set(arr)];
console.log(result);
//2. 交集
let arr2 = [4,5,6,5,6];
//filter创建一个新数组,符合条件的都放进去
//filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
//filter()接收的回调函数,其实可以有多个参数。
//通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:
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. 并集
//[...arr, ...arr2]合并数组
//放入集合去重
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);
</script>
15、Map集合
概述: ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类 型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和 『for…of…』进行遍历;
Map 的属性和方法:
1. size 返回 Map 的元素个数;
2. set 增加一个新元素,返回当前 Map;
3. get 返回键名对象的键值;
4. has 检测 Map 中是否包含某个元素,返回 boolean 值;
5. clear 清空集合,返回 undefined;
<script>
//声明 Map
let m = new Map();
//添加元素
m.set('name','尚硅谷');
m.set('change', function(){
console.log("我们可以改变你!!");
});
let key = {
school : 'ATGUIGU'
};
m.set(key, ['北京','上海','深圳']);
//size
console.log(m.size);
//删除
m.delete('name');
//获取
console.log(m.get('change'));
console.log(m.get(key));
//清空
m.clear();
//遍历
for(let v of m){
console.log(v);
}
// console.log(m);
</script>
16、class类
概述: ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键 字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做 到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;
知识点:
1. class 声明类;
2. constructor 定义构造函数初始化;
3. extends 继承父类;
4. super 调用父级构造方法;
5. static 定义静态方法和属性;
6. 父类方法可以重写;
<script>
//手机
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);
//class
class Shouji{
//构造方法 名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//添加方法
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
call(){
console.log("我可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
</script>
class静态成员:
name既不在实例对象上也不在原型上,故报错。
<script>
function Phone(){
}
Phone.name = '手机';
Phone.change = function(){
console.log("我可以改变世界");
}
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
//name既不在实例对象上也不在原型上,故报错
console.log(nokia.name);
// nokia.change();
console.log(nokia.size);
class Phone{
//静态属性
static name = '手机';
static change(){
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name);
console.log(Phone.name);
</script>
ES5构造函数实现继承:
<script>
// ES5构造函数继承
// 手机
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log("我可以打电话!");
}
// 智能手机
function SmartPhone(brand, price, color, size) {
//借用Phone函数,给this执行,this是new出来的s
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
// 设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;
// 声明子类的方法
SmartPhone.prototype.photo = function () {
console.log("我可以拍照!");
}
SmartPhone.prototype.game = function () {
console.log("我可以玩游戏!");
}
const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
console.log(chuizi);
chuizi.call();
chuizi.photo();
chuizi.game();
</script>v
ES6class类继承:
<script>
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
call(){
console.log("我可以打电话!!");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩游戏");
}
call(){
console.log('我可以进行视频通话');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
</script>
子类对父类方法重写:
//调用子类重写的方法
xiaomi.call();
//调用父类的方法
xiaomi.__proto__.__proto__.call()
class中的getter和setter设置:
<script>
// get 和 set
class Phone{
get price(){
console.log("价格属性被读取了");
return '123';
}
set price(newVal){
console.log('价格属性被修改了');
console.log(newVal)
}
}
//实例化对象
let s = new Phone();
console.log(s.price);
s.price = 'free';
console.log(s.price);
</script>
17、数值扩展
Number.EPSILON:
Number.EPSILON 是 JavaScript 表示的最小精度;
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;
二进制和八进制:
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;
Number.isFinite() 与 Number.isNaN() :
Number.isFinite() 用来检查一个数值是否为有限的;
Number.isNaN() 用来检查一个值是否为 NaN;
Number.parseInt() 与 Number.parseFloat():
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;
Math.trunc:
用于去除一个数的小数部分,返回整数部分;
Number.isInteger:
Number.isInteger() 用来判断一个数值是否为整数;
<script>
//0. 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.30000000000000004
console.log(0.1 + 0.2 === 0.3);//false
console.log(equal(0.1 + 0.2, 0.3))//true
//1. 二进制和八进制
let b = 0b1010;//二进制
let o = 0o777;//八进制
let d = 100;//十进制
let x = 0xff;//十六进制
console.log(x);
//2. Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100));//true
console.log(Number.isFinite(100/0));//false
console.log(Number.isFinite(Infinity));//false
//3. Number.isNaN 检测一个数值是否为 NaN
console.log(Number.isNaN(123)); //false
//4. Number.parseInt Number.parseFloat字符串转整数
console.log(Number.parseInt('5211314love'));//5211314
console.log(Number.parseFloat('3.1415926神奇'));//3.1415926
//5. Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5));//true
console.log(Number.isInteger(2.5));//false
//6. Math.trunc 将数字的小数部分抹掉
console.log(Math.trunc(3.5));///3
//7. Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100));//1
console.log(Math.sign(0));//0
console.log(Math.sign(-20000));//-1
</script>
18、对象扩展
概述: ES6 新增了一些 Object 对象的方法:
1. Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);
2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;
3. proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;
<script>
//1. Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120));// true
console.log(Object.is(NaN, NaN));// true
console.log(NaN === NaN);// false
//2. Object.assign 对象的合并
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: 'atguigu.com',
pass: 'iloveyou',
test2: 'test2'
}
//属性重名,后面的属性值覆盖前面的属性值
console.log(Object.assign(config1, config2));
//3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
//Object实例对象
const school = {
name: '尚硅谷'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));//cities
console.log(school);//school.__proto__===cities
</script>
19、模块化
概述: 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;
模块化的好处:
模块化的优势有以下几点: 1. 防止命名冲突; 2. 代码复用; 3. 高维护性;
模块化规范产品:
ES6 之前的模块化规范有:
1. CommonJS => NodeJS、Browserify; 2. AMD => requireJS; 3. CMD => seaJS;
ES6 模块化语法:
模块功能主要由两个命令构成:
export 和 import; export 命令用于规定模块的对外接口(导出模块); import 命令用于输入其他模块提供的功能(导入模块);
简单使用:
ES6暴露数据语法汇总:
m.js(逐个导出模块):
n.js(统一导出模块):
o.js(默认导出模块):
<script type="module" >
//导入m.js
import * as m from "./m.js";
import * as n from "./n.js";
import * as o from "./o.js";
console.log(m)
console.log(n)
console.log(o)
o.default.change()
</script>
ES6导入模块语法汇总:
<script type="module" >
//1. 通用方式
//导入m.js
import * as m from "./m.js";
import * as n from "./n.js";
import * as o from "./o.js";
console.log(m)
console.log(n)
console.log(o)
o.default.change()
//2.结构赋值
import{school,show} from "./m.js";
console.log(school,show);
import{school as atguigu,findJob} from "./n.js";
console.log(atguigu,findJob);
import{default as g} from "./o.js";
console.log(g);
//3.简便形式,针对默认暴露
import m3 from "./o.js";
console.log(m3)
</script>
使用模块化的另一种方式:
<script src="./app.js" type="module"></script>
20、Babel对ES6模块化代码转换
Babel概述:
Babel 是一个 JavaScript 编译器;
Babel 能够将新的ES规范语法转换成ES5的语法;
因为不是所有的浏览器都支持最新的ES规范,所以,一般项目中都需要使用Babel进行转换;
步骤:使用Babel转换JS代码——打包成一个文件——使用时引入即可;
三、ES7 新特性
0、功能概述
1、Array.prototype.includes
判断数组中是否包含某元素,语法:arr.includes(元素值);
2、指数操作符
幂运算的简化写法,例如:2的10次方:2**10;
1、Array.prototype.includes
概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值; 判断数组中是否包含某元素,语法:arr.includes(元素值);
<script>
// includes indexOf
const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
//判断
console.log(mingzhu.includes('西游记'));
console.log(mingzhu.includes('金瓶梅'));
// **
console.log(2 ** 10);//
console.log(Math.pow(2, 10));
</script>
四、ES8 新特性
0、功能概述
1、async 和 await
简化异步函数的写法;
2、对象方法扩展
对象方法扩展;
1、async 和 await 概述:
async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;
简化异步函数的写法;
async 函数:
概述: 1. async 函数的返回值为 promise 对象; 2. promise 对象的结果由 async 函数执行的返回值决定;
// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
//抛出错误, 返回的结果是一个失败的 Promise
//返回的结果如果是一个 Promise 对象
<script>
//async 函数
async function fn(){
// 返回一个字符串
// return '尚硅谷';
// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
// return;
//抛出错误, 返回的结果是一个失败的 Promise
// throw new Error('出错啦!');
//返回的结果如果是一个 Promise 对象
return new Promise((resolve, reject)=>{
resolve('成功的数据');
// reject("失败的错误");
});
}
const result = fn();
//调用 then 方法
result.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
</script>
await 表达式:
概述:
1. await 必须写在 async 函数中;
2. await 右侧的表达式一般为 promise 对象;
3. await 返回的是 promise 成功的值;
4. await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理;
<script>
//创建 promise 对象
const p = new Promise((resolve, reject) => {
// resolve("用户数据");
reject("失败啦!");
})
// await 需要放在 async 函数中.
async function main() {
try {
//await p;返回promise对象成功的值
let result = await p;
//
console.log(result);
} catch (e) {
console.log(e);
}
}
//调用函数
main();
</script>
async 和 await 读取文件案例:
//1. 引入 fs 模块
const fs = require("fs");
//读取『为学』
//返回结果为一个promise对象
function readWeiXue() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/为学.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readChaYangShi() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧诗.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readGuanShu() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/观书有感.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
//声明一个 async 函数
//1. async 函数的返回值为 promise 对象;
//2. promise 对象的结果由 async 函数执行的返回值决定;
async function main(){
//获取为学内容
//await readWeiXue();返回的是promise成功的值
let weixue = await readWeiXue();
//获取插秧诗内容
let chayang = await readChaYangShi();
// 获取观书有感
let guanshu = await readGuanShu();
console.log(weixue.toString());
console.log(chayang.toString());
console.log(guanshu.toString());
}
async 和 await 结合发送ajax请求:
<script>
// 发送 AJAX 请求, 返回的结果是 Promise 对象
function sendAJAX(url) {
return new Promise((resolve, reject) => {
//1. 创建对象
const x = new XMLHttpRequest();
//2. 初始化
x.open('GET', url);
//3. 发送
x.send();
//4. 事件绑定
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//成功啦
resolve(x.response);
}else{
//如果失败
reject(x.status);
}
}
}
})
}
//promise then 方法测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{
// console.log(value);
// }, reason=>{})
// async 与 await 测试 axios
async function main(){
//发送 AJAX 请求
let result = await sendAJAX("https://api.apiopen.top/getJoke");
//再次测试
let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')
console.log(tianqi);
}
main();
</script>
2、对象方法扩展
Object.values、Object.entries和 Object.getOwnPropertyDescriptors:
1. Object.values()方法:返回一个给定对象的所有可枚举属性值的数组;
2. Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组;
3. Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;
<script>
//声明对象
const school = {
name:"尚硅谷",
cities:['北京','上海','深圳'],
xueke: ['前端','Java','大数据','运维']
};
//获取对象所有的键
console.log(Object.keys(school));
//获取对象所有的值
console.log(Object.values(school));
//entries
console.log(Object.entries(school));
//创建 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
}
});
</script>
五、ES9 新特性
0、功能概述
1、Rest 参数与 spread 扩展运算符
概述: Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了 像数组一样的 rest 参数和扩展运算符;
在对象中使Rest参数与spread扩展运算符;
<!--
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
-->
<script>
//rest 参数
//解构赋值
function connect({host, port, ...user}){
console.log(host);
console.log(port);
//一个object对象
console.log(user);
}
//传入一个对象作为参数
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
//对象合并
const skillOne = {
q: '天音波'
}
const skillTwo = {
w: '金钟罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龙摆尾',
d:'flash'
}
//对象的合并
const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng)
</script>
2、正则扩展:命名捕获分组
简化和增强正则匹配;
概述: ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强;
<script>
//声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// //提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;
// //执行
const result = reg.exec(str);
//一个数组
console.log(result);
console.log(result[1]);
console.log(result[2]);
let strr = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
const regx = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const resultt = regx.exec(strr);
//拥有groups属性
console.log(resultt)
console.log(resultt.groups.url);
console.log(resultt.groups.text);
</script>
3、正则扩展:反向断言
概述: ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选;
<script>
//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
//提取数字555
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result);
//反向断言
//判断数字前面是不是‘么’
const regx = /(?<=么)\d+/;
const resultt = regx.exec(str);
console.log(resultt);
</script>
4、正则扩展:dotAll 模式
概述: 正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现;
<script>
//dot . 元字符 除换行符以外的任意单个字符
//模板字符串
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>\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);
</script>
六、ES10 新特性
0、功能概述
1、Object.fromEntries 将二维数组或者map转换成对象;
2、trimStart 和 trimEnd 去除字符串前后的空白字符;
3、Array.prototype.flat 与 flatMap 将多维数组降维;
4、Symbol.prototype.description 获取Symbol的字符串描述;
1、Object.fromEntries
概述:将二维数组或者map转换成对象; 之前学的Object.entries是将对象转换成二维数组;
<script>
//参数接收二维数组
const result = Object.fromEntries([
['name','尚硅谷'],
['xueke', 'Java,大数据,前端,云计算']
]);
//返回一个对象
console.log(result)
//传入一个Map作为参数
//返回一个对象
const m = new Map();
m.set('name','ATGUIGU');
const resultt = Object.fromEntries(m);
console.log(resultt)
//Object.entries ES8
//将一个对象转换为一个二维数组
const arr = Object.entries({
name: "尚硅谷"
})
console.log(arr);
</script>
2、trimStart 和 trimEnd
<script>
// trim
let str = ' iloveyou ';
console.log(str);
//清除左侧空白
console.log(str.trimStart());
//清除右侧空白
console.log(str.trimEnd());
</script>
3、Array.prototype.flat 与 flatMap
概述: 将多维数组转换成低维数组;
<script>
//flat 平
//将多维数组转化为低位数组
const arr = [1,2,3,4,[5,6]];
const arr1 = [1,2,3,4,[5,6,[7,8,9]]];
//参数为深度 是一个数字,需要降低多少维
console.log(arr.flat());
console.log(arr1.flat(2));
//flatMap
const arr2 = [1,2,3,4];
//传入一个回调函数
const result = arr2.map(item => [item * 10]);
const resultt = arr2.flatMap(item => [item * 10]);
//一个二维数组
console.log(result);
//一个一维数组
console.log(resultt);
</script>
4、Symbol.prototype.description
概述: 获取Symbol的描述字符串;
<script>
//创建 Symbol
let s = Symbol('尚硅谷');
console.log(s.description);//尚硅谷
</script>
七、ES11 新特性
0、功能概述
1、String.prototype.matchAll 用来得到正则批量匹配的结果;
2、类的私有属性 私有属性外部不可访问直接;
3、Promise.allSettled 获取多个promise执行的结果集;
4、可选链操作符 简化对象存在的判断逻辑;
5、动态 import 导入 动态导入模块,什么时候使用什么时候导入;
6、BigInt大整型;
7、globalThis 对象 始终指向全局对象window;
1、String.prototype.matchAll
概述: 用来得到正则批量匹配的结果;
<script>
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);
</script>
2、类的私有属性
概述: 私有属性外部不可直接访问;
<script>
class Person{
//公有属性
name;
//私有属性
#age;
#weight;
//构造方法
constructor(name, age, weight){
this.name = name;
this.#age = age;
this.#weight = weight;
}
//在内部声明方法
show(){
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
//实例化
const girl = new Person('晓红', 18, '45kg');
console.log(girl)
console.log(girl.name);
//Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
//console.log(girl.#age);
//console.log(girl.#weight);
//在外部访问
girl.show();
</script>
3、Promise.allSettled
概述:处理批量异步任务结果, 获取多个promise执行的结果集;
<script>
//声明两个promise对象
const p1 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('商品数据 - 1');
},1000)
});
const p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
//resolve('商品数据 - 2');
reject('出错啦!');
},1000)
});
//调用 allsettled 方法
//返回一个promise对象,其状态始终是成功的,成功的值是一个数组,包含p1, p2的状态和值
const result = Promise.allSettled([p1, p2]);
console.log(result)
//返回一个promise对象
//p1,p2都成功,则res成功,有一个失败,则失败。
const res = Promise.all([p1, p2]);
console.log(res);
</script>
4、可选链操作符
概述: 如果存在则往下走,省略对对象是否传入的层层判断;
<script>
// ?.
function main(config){
// const dbHost = config && config.db && config.db.host;
//先判断config有没有传入,有再.db,如果有db,再.host
const dbHost = config?.db?.host;
console.log(dbHost);
}
//传入一个对象
main({
db: {
host:'192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username:'admin'
}
})
</script>
5、动态 import 导入
概述: 动态导入模块,什么时候使用时候导入;
html:引入app.js文件
hello.js:导出模块
app.js:动态引用模块
6、BigInt
概述: 更大的整数
<script>
//大整形
let n = 521n;
console.log(n, typeof(n));//521n 'bigint'
//函数
let n1 = 123;
//转换为BigInt
console.log(BigInt(n1));//123n
//Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is not an integer
//console.log(BigInt(1.2));
//大数值运算
//最大安全整数
let max = Number.MAX_SAFE_INTEGER;
console.log(max);//9007199254740991
console.log(max + 1);//9007199254740992
console.log(max + 2);//9007199254740992
console.log(BigInt(max))//9007199254740991n
console.log(BigInt(max) + BigInt(1))//9007199254740992n
console.log(BigInt(max) + BigInt(2))//9007199254740993n
</script>
7、globalThis 对象
概述: 始终指向全局对象window;
JavaScript环境:
node.js环境: