1:变量声明不能重复
2:块级作用域
3:不存在变量提升
4:不影响作用域链
1:用于声明常量,一定要赋初始值
2:一般用大写(潜规则)
3:常量的值不能修改
4:块级作用域
5:对于数组或对象的元素的修改,不算对常量的修改,不会报错
const F3 = ['白素贞', '小青', '许仙'];
let [bai, qing, xu] = F3;
console.log(bai) // 白素贞
console.log(qing) // 小青
console.log(xu) // 许仙
const dong = {
name: "东子",
wife: "奶茶妹妹",
age: 40,
save: function () {
console.log("捐东西")
}
}
let {name,wife,age,save} = dong;
console.log(name,wife,age); // 东子 奶茶妹妹 40
console.log(save); // ƒ () { console.log("捐东西") }
save(); // 捐东西
1:内容中可以直接出现换行符
2:变量拼接
let age = 80;
let out = `我今年${age}岁了。`
ES6里面允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
let name = "兵长";
let kill = function (){
console.log("我能砍巨人")
}
const liweier= {
name,
kill,
fly () {
console.log("我能飞")
}
}
上面写法等价于
const liweier= {
name: name,
kill: kill,
fly: function () {
console.log("我能飞")
}
}
let fn = (a,b) => {return a + b}
1:this 是静态的,始终指向函数声明时所在作用域下的 this 的值
2:不能作为构造函数实例化对象
let Fn = (name, age) => {
this.name = name
this.age = age
}
let fn = new Fn('小明', 29); // 报错
// Uncaught TypeError: Fn is not a constructor
// at :1:10
3:不能使用arguments变量
let fn = () => {console.log(arguments)}
fn(1,2) // 报错,找不到arguments
// VM845:1 Uncaught ReferenceError: arguments is not defined
// at fn (:1:29)
//at :1:1
4:关于箭头函数的简写
1):省略小括号,当形参只有一个的时候
let add = n => {
return n + n
}
2):省略花括号,当代码体只有一条语句的时候,此时,return 也必须省略,而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(2)) // 4
实践一下吧:
需求:返回数组中的偶数
let arr = [1,2,3,4,5,6,6,7];
let result = arr.filter(item => item%2 === 0) // [2, 4, 6, 6]
1:形参初始值,具有默认值的参数一般放在最后
function add (a, b, c=10) {
return a + b + c
}
let result = add(1,2) // 13
2:与结构赋值结合
function connect({host="127.0.0.1", username}) {
console.log(host, username)
}
connect({host: "192.168.1.1", username: "root"})
ES6引入rest参数,用于获取函数的实参。用来代替arguments
// ES5的arguments
function data () {
console.log(arguments)
}
data(1,2,3)
// ES6中的rest参数
function data (...args) {
console.log(args) // [1,2,34]
}
data(1,2,34)
// rest 参数必须放到最后
function data (a,b,...args) {
console.log(a) // 1
console.log(b) // 2
console.log(args) // [3,4,5]
}
data(1,2,3,4,5)
扩展运算符能将 数组 转化为逗号分隔的参数序列
const tfboys = ['易烊千玺', '王源', '王俊凯'];
function data () {
console.log(arguments)
}
data(...tfboys) // 相当于 data('易烊千玺', '王源', '王俊凯')
1:数组的合并
const arr1 = [1,2]
const arr2 = [3,4]
// ES5 写法
const newArr = arr1.concat(arr2)
// ES6 写法
const newArr = [...arr1, ...arr2]
2:数组的克隆(浅克隆)
var arr = [1,2,3];
var arrCopy = [...arr]; // [1, 2, 3]
3:将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
const divAll = [...divs]
// Es6 数组去重
const arr = [1,1,2,3,3]
const result = [...new Set(arr)]; // [1,2,3]
或
const result = Array.from(new Set(arr)); // [1,2,3]
ES6引入了一种新的数据类型Symbol(JS的第7种数据类型,原来的6种有:undefined,null,number,string,boolean,object),表示独一无二的值,是一种类似于字符串的数据类型。
特点:
1:Symbol的值是唯一的,用来解决命名冲突的问题。
2:Symbol不能与其他数据进行运算。
3:Symbol定义的对象属性不能使用for…in循环遍历
ES6提供的新的数据结构,类似于数组,但是里面的每个值都是唯一的。
let s = new Set([1,2,3])
// 元素个数
s.size // 3
// 新增元素
s.add(4) // Set(4) {1, 2, 3, 4}
// 删除元素
s.delete(3) // true
console.log(s) // Set(3) {1, 2, 4}
//检测
s.has(2) // true
// 清空
s.clear()
Set实践
let arr = [1,1,2,3,4,4,5,3]
let arr2 = [4,5,6,5,6]
1:数组去重
2:求交集
3:求并集
4:求差集
// 1: 去重
let arr = [1,1,2,3,4,4,5,3];
let result = [... new Set(arr)]
// 2:交集
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item)); // [4,5]
// 3:并集
let result = [...new Set([...arr, ...arr2])];
// 4:差集(arr不含arr2的元素)
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item))); // [1, 2, 3]
类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值都可以作为键
// 声明
let m = new Map();
// 添加元素
m.set('name', '孙杨');
m.set('swim', function () {console.log("会游泳")})
let key = {
des: "这是一个对象"
}
m.set(key, "对象也能作为键")
console.log(m)
// size
m.size // 3
// 删除
m.delete('name') // true
// 获取
m.get(key) // "对象也能作为键"
// 清空
m.clear()
// 遍历
for (let v of m) {console.log(v)}
1:Number.EPSILON 是 js中表示的最小精度
console.log(0.1+0.2 === 0.3) // false
function equl(a, b) {
if (Math.abs(a-b) < Number.EPSILON) {
return true;
} else {
return false;
}
}
equl(0.1+0.2, 0.3) // true
2:二进制、八进制
let num = 0b01010; // 二进制
console.log(num) // 10
let num = 0o777; // 八进制
console.log(num) // 511
let num = 100; // 十进制
console.log(num); // 100
let num = 0xff; // 十六进制
console.log(num); // 255
3:Number.isFinite 检测一个数字是否为有限数
Number.isFinite(100); // true
Number.isFinite(100/0); // false
4:Number.isNaN 检测一个值是否为NaN
isNaN()是ES5的方法,Number.isNaN()是ES6的方法
可能有一些童鞋会认为 isNaN直译为“是不是 NaN”,其本意不是,isNaN本意是通过Number方法把参数转换成数字类型,如若转换成功,则返回false,反之返回true,它只是判断参数是否能转成数字,不能用来判断是否严格等于NaN。,如果要判断某个值是否严格等于NaN不能用这个方法
ES6提供了Number.isNaN方法用来判断一个值是否严格等于NaN,它会首先判断传入的值是否为数字类型,如不是,直接返回false。
区别:
isNaN方法首先转换类型,而Number.isNaN方法不用;
isNaN不能用来判断是否严格等于NaN,Number.isNaN方法可用
本知识点引用地址链接
Number.isNaN(123)// false
Number.isNaN("asd") // false
let a= 'as';
Math.floor(a);//NaN
Number.isNaN(Math.floor(a)); // true
5:Number.parseFloat 和 Number.parseInt
Number.parseFloat('2.22asd') // 2.22
Number.parseInt('123asd') // 123
6:Number.isInteger 判断十足是否为整数
Number.isInteger(3.3) // false
Number.isInteger(3) // true
7:Math.trunc 舍去数值小数部分
Math.trunc(3.33) // 3
8:Math.sign 判断数值 大于0,等于0还是小于0
Math.sign(-11) // -1
Math.sign(0) // 0
Math.sign(112) // 1
1:Onject.is 判断两个值是否完全相等(类似于 === )
Object.is(12,12)// true
Object.is(NaN,NaN) // true
NaN === NaN // flase
2:Object.assign 对象合并
const obj1 = {
name: '小明',
age: 22,
weight: '66kg'
}
const obj2 = {
name: '小花',
age: 18,
height: '165cm'
}
Object.assign(obj1, obj2) // {name: "小花", age: 18, weight: "66kg", height: "165cm"}
// 参数可以传多个,如有同名,则后面的会把前面的覆盖
const obj3 = {
name: "小红",
age: 88
}
Object.assign(obj1, obj2, obj3) // {name: "小红", age: 88, weight: "66kg", height: "165cm"}
模块化是指将一个较大的程序文件,拆分成一个个小文件,最后又将这些小文件组合起来。
优点:
1):防止命名冲突。每个小文件之间都是独立的,声明相同变量时不会产生冲突。
2):代码复用。
3):利于维护。
export:规定模块的对外接口
import:引用其他模块提供的功能
暴露方式有三种:
// 分别暴露
export let name = "小明";
export function fn () {
console.log("这是一个方法")
}
// 统一暴露
let name = "xiaoming";
function fn () {
console.log("这是方法")
}
export {name, fn};
// 默认暴露
export default {
name: "小明",
fn: function () {
console.log("这是一个方法")
}
}
导入的方式:
//1: 通用导入
import * as test from "../../xxx.js"
//2: 结构赋值形式
import {name, fn} from "../../xxx.js"
// 可以取别名
import {name as xiaoMing, fn} from "../../xx.js"
// 导入default类型的
import {default as test} from "../xxx.js"
//3:简便形式(只针对默认暴露)
import test from "../xx.js"
const arr = ["小明", "小红", "小华"];
arr.includes("小明"); // true
arr.includes("小白"); // false
console.log(2 ** 10); // 1024
// 等同于Math.pow
console.log(Math.pow(2, 10));
// async函数
async function fn () {
// 返回一个字符串
// return "返回的数据"
// 如果返回的不是一个promise类型的对象,返回的结果就是一个成功的promise对象
// 抛出错误,则返回一个失败的promise对象
// throw "错误拉"
// 如果返回一个promise对象
return new Promise((resolve, reject) => {
resolve("这是成功的值");
reject("这是失败的值")
})
}
let result = fn();
console.log(result);
// 因为返回的是promise类型的对象,所以可以使用.then
result.then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
1:await 必须写在async函数中
2:await右侧一般为promise对象
3:await返回的是promise成功的值
4:await如果返回失败,就是抛出异常,用try…catch捕获处理
创建一个promise对象
const p = new Promise((resolve, reject) => {
resolve("获取到成功的数据");
reject("报错了")
})
// await 要放在async函数中
async function test () {
try {
let result = await p;
console.log(result);
} catch(e){
console.error(e)
}
}
// 调用函数
test();
发送 AJAX请求
// 发送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://img-home.csdnimg.cn/data_json/toolbar/toolbar0812.json").then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
// async await测试
async function test() {
let res = await sendAjax("https://img-home.csdnimg.cn/data_json/toolbar/toolbar0812.json");
console.log(res)
}
test()
const obj = {
name: "小明",
cars: ["宝马", "奔驰", "奥迪"],
hobby: ["篮球", "swim"]
}
// 获取对象所有的键
console.log(Object.keys(obj)); //["name", "cars", "hobby"]
// 获取对象所有的值
console.log(Object.values(obj));
// 0: "小明"
// 1: (3) ["宝马", "奔驰", "奥迪"]
// 2: (2) ["篮球", "swim"]
在ES9中提供了像数组一样的rest参数和扩展运算符
function test ({name, age, ...other}) {
console.log(name); // 小明
console.log(age); // 30
console.log(other); // {height: "180cm", weight: "70kg"}
}
test({name:"小明", age:30, height:"180cm", weight:"70kg"});
const a = {name: "小红"};
const b = {age: 20};
const c = {cars: ["宝马", "法拉利"]};
// 对象的合并
const all = {...a, ...b, ...c};
console.log(all); // {name: "小红", age: 20, cars: Array(2)}
// ES5 方式
let str = "百度知道";
const reg = /(.*)<\/a>/;
const res = reg.exec(str);
console.log(res);
// 0: "百度知道"
// 1: "http://www.baidu.com"
// 2: "百度知道"
// groups: undefined
// index: 0
// input: "百度知道"
// 这个时候我们要去获取url和文本的话,可以用下标去获取,但是不方便维护,以后如果要获取字符串中的其他值,很可能要去改下标
console.log(res[1]); // http://www.baidu.com
console.log(res[2]); // 百度知道
// ES9中的命名捕获
let str = "百度知道";
const reg = /(?.*)<\/a> /;
const res = reg.exec(str);
console.log(res);
// 0: "百度知道"
// 1: "http://www.baidu.com"
// 2: "百度知道"
// groups: {url: "http://www.baidu.com", text: "百度知道"}
// index: 0
// input: "百度知道"
// 区别,捕获到的url和text会在groups中,这是我们就可以获取groups中的值
console.log(res.groups.url); // http://www.baidu.com
console.log(res.groups.text); // 百度知道