ES6
let变量声明
// 声明变量
let a;
// 1.变量不能重复声明
let b = 1 ;
let b = 2; //会报错,如果使用var声明不会报错。
// 2.块级作用域
// if else、whild、for这些都是块级作用域
{
//声明的变量只在代码块中才有效
let c = 1;
}
console.log(c) // 报错,如果上面变量c,是var声明的不会报错,var没有块级作用域。
// 3.不存在变量提升
console.log(d) //报错
let d = 4
const声明常量
// 声明常量
const a = '111';
// 1.一定要赋初始值
const b //错误
// 2.一般常量大写
const A = 1
// 3.常量值不能修改
const A = 1
A = 2 //错误
// 4.块级作用域
{
const C = 1
}
console.log(C) //错误
// 5.对于数组和对象的元素修改,不会报错,因为常量指向的是地址,地址不变
const TE = ['a','b']
TE.push('c') //正常
TE = 100 //报错
变量解构赋值
// ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,即解构赋值
// 1.数组结构
const A = ['1','2','3']
let [aa,bb,cc] = A
// 2.对象结构
const AB = {name : 'zhangsan',age :'16', xihao : fucntion(){}}
let {name1,age1,xihao1} = AB
模板字符串
// 引入了新的声明字符串的方式,``,ES5是'',""
// 1.声明
let str = `aaa`
// 2.内容中可以直接出现换行符
// 原来的''
let str1 ='aaa
ccc' //报错
// 现在的``
let str2 = `aaa
ccc` //正常
// 3.变量拼接${}
let aa = 'hello'
let bb = `${aa} world`
对象的简化写法
let name = 'aaa'
let change = function(){}
// 1.可以在大括号里,直接写入变量和函数,作为对象的属性和方法
const bb ={
name,
change,
impr(){}
}
// 等价于
const bb ={
name: name,
change: change,
impr: function(){}
}
箭头函数
// 可以使用箭头 => 定义函数
let fn = (a,b) => {return a+b}
// 1.this是静态的,this始终指向函数声明时所在作用域下的this的值。
let fnn1 = () => {
console.log(this) //=>在全局作用域下声明的,所以this指向window
}
let div = document.querySelector('div')
div.addEventListener('click',function(){console.log(this)}) //this指向div
div.addEventListener('click',() => {console.log(this)}) //this指向window
// 2.不能作为构造实例化对象
let Person = (name,age) => {this.name = name ;this.age = age;}
let ms = new Person('zhangsan', 3) //报错
// 3.不能使用arguments变量
let fn = () => {console.log(arguments)} //报错
// 4. 箭头函数的简写
// 1)省略小括号,当形参有且只有一个时
let fn = a => {return a}
// 1)省略小括号,当代码体只有一条语句时,可以省略花括号,return 也要省略,语句的执行结果就是函数的返回值。
let fn = b => b * b
- 箭头函数适合与this无关的回调,如定时器setTimeout(),数组的方法filter()回调
- 箭头函数不适合与this有关的回调,Dom元素的事件回调,对象方法
函数参数设置默认值
// 1.具有默认值的参数,一般位置靠后
function add(a,b,c=20){return a+b+c}
add(1,2,3) //输出6
add(1,2) //输出23,当c没有传值时用默认值20
// 2. 与解构赋值一起使用
function con({name="wang",age}){
console.log(name)
}
con({name:"zhangsan",age:16}) //输出zhangsan
con({age:16}) //输出wang
rest参数
- rest参数:用于获取函数的实参,用来代替arguments
// rest参数:用于获取函数的实参
function con(...args){
console.log(args)
}
con('1','2','3','4','5') //输出的是数组['1','2','3','4','5'],可以用数组的一些方法
// 当有多个参数时,rest参数要放到参数最后
function con(name,age,...args){
console.log(args)
}
con('1','2','3','4','5') //输出的是数组['3','4','5']
扩展运算符…
- …扩展运算符可以将数组转换为逗号分隔的参数序列
const arr = ['aaa','bbb','ccc']
function con(){
console.log(arguments)
}
con(...arr) //里面有三个元素
// 等价于
//即 ...arr是:把数组['aaa','bbb','ccc'] --> 转化为逗号分隔的参数序列 'aaa','bbb','ccc'
con('aaa','bbb','ccc')
//1.数组合并
const arr1 = ['aaa','bbb']
const arr2 = ['ccc','ddd']
//...arr1相当于'aaa','bbb' ..arr2相当于'ccc','ddd'
const arr = [...arr1,...arr2] //输出 ['aaa','bbb'.'ccc','ddd']
//2.数组克隆,浅拷贝,如果数组里面还有引用,则只复制地址
const arr3 = ['aaa','bbb']
const arr4 = [...arr3]
//将伪数组转为真正的数组
let div = document.querySelector('div')
let divs = [...div] //输出的是数组
原始数据类型Symbol
- Symbol:表示独一无二的值,用于解决命名冲突
- Symbol值不能与其他数据进行运算
- Symbo定义的对象属性不能用for…in遍历循环,但可以用Reflect.ownKeys获取对象的所有键名
//创建symbol
let s =Symbol()
//创建symbol
let s1 =Symbol("a") //里面的a只是一个标志,表示这个symbol是干什么用的
let s2 =Symbol("a")
console.log(s1===s2)//输出false
//创建symbol
let s3 =Symbol.for("a")
let s4 =Symbol.for("a")
console.log(s3===s4)//输出true
//给对象添加symbol属性和方法
let use={}
let method = {
up:symbol()
}
use[method.up] = function(){console.log("111")}
//给对象添加symbol属性和方法
let met = {
up : "111"
[Symbol('sss')]: function(){}
}
Symbol内置属性
- 控制对象在特定场景下的表现
const aa = [1,2,3]
const bb = [4,5,6]
// Symbol.isConcatSpreadable作为对象(bb)的一个属性,扩展对象的功能
bb[Symbol.isConcatSpreadable] = false
console.log(aa.concat(bb)) //输出[1,2,3,[4,5,6]]
迭代器Iteractor
- Iteractor是一种接口,就是对象里的一个属性Symbol.Iteractor,遍历命令for of
- Array、Arguments、Set、Map、String、TypedArray、NodeList都具备 Iteractor接口(就是对象里的一个属性)
let aa = ['a','b','c','d']
for(let da of aa){
console.log(da) // 输出a,b,c,d
}
const ban = {
name: "yi",
stus: ['xiaoming','xiaoning','xiaotian'],
//正常情况对象是不能 for of 遍历的,因为没有对象是没有iterator
//手动加个interator
[Symbol.iterator](){
let index = 0;
let _this = this;
return {
next: function(){
if(index< _this.stus.length){
const value={value: _this.stus[index],done: false}
index++;
return value
}else{
return {value: undefined,done: true}
}
}
}
}
}
// 遍历对象
for (let v of ban){
console.log(v)
}
生成器
- 生成器:就是一个特殊的函数,是ES6提供一种异步编程的解决方案
//1.声明要有*号
function * hanshu(){
console.log("111")
yield 'yiyi' //yield 是函数代码的分隔符,3个yield将代码分成4块
console.log("222")
yield 'erer'
console.log("333")
yield 'sansan'
console.log("444")
}
//执行要调next
let iterator = hanshu()
console.log(iterator.next()) // iterator.next()返回结果是一个对象,里面包括value和done {value: "yiyi",done false}
console.log(iterator.next()) // {value: "erer",done false}
console.log(iterator.next()) // {value: "sansan",done false}
console.log(iterator.next()) // {value: undefined,done true}
//也可以用for of遍历
for (let v of iteractor){
console.log(v)
}
function * hanshu(arg){
console.log(arg)
let one = yield 'yiyi'
console.log(one) //此处输出的是222
let two = yield 'erer'
console.log(two) //此处输出的是333
}
//生成器函数可以传参数
let iterator = hanshu("111")
console.log(iterator.next())
//next函数也可以传参数,
console.log(iterator.next("222")) //输入的222作为第一个yield的返回值
console.log(iterator.next("333")) //输入的222作为第二个yield的返回值
//异步编程
function one (){
setTimeout(()=>{console.log("111");iterator.next()},1000)
}
function two (){
setTimeout(()=>{console.log("222");iterator.next()},2000)
}
function * funn(){
yield one();
yield two()
}
let iterator = funn()
iterator.next()
set集合
- 成员的值是唯一的
// 声明一个set集合
let s = new Set()
// 可以传入参数,里面是可迭代数据
let s = new Set(['1','2'])
s.size() //集合个数
s.add('3') //添加
s.delete('2') //删除
s.has('2') //集合中是否含有
s.clear() //清空集合
//数组去重
let arr = ['1','2','3','4','2','3']
let arrs = [...new Set(arr)]
Map
- 键值对的集合。其中键的范围不限于字符串,各种类型值都行,比如对象也可以当作键
let m = new Map()
m.size() //集合个数
m.set('name',"111") //添加
m.delete('name') //删除
m.get('name') //获取
m.has('name') //集合中是否含有
m.clear() //清空集合
class类
// ES5 构造函数
function Phone(brand) {
this.brand = brand
}
// 构造函数实例化对象
let huawei = new phone('hua')
// ES6 class + 类名
class phone2{
// 构造方法,名字固定,使用new+类名时,就会自动执行
constructor(brand){
this.brand = brand
}
//方法 必须使用该语法,不能用ES5的语法call: function()
call(){}
}
let xiaomi = new phone2('xiaom')
静态成员
// 构造函数
function Phone() {
}
//原型对象属性
Phone.prototype.nam="zhangsan"
//构造函数本身也是对象,可以添加属性和方法
//这些属性只属于函数对象,也称为静态成员
Phone.name ="xiaoming"
Phone.change= function(){console.log("666")}
//实例化对象
let huawei = new phone()
console.log(huawei.name) //输出undefined ,即实例对象huawei没有构造函数对象的属性的
//即实例对象是实例对象,函数对象是函数对象,它们属性是不通的。
huawei.change() //报错
//实例对象属性和原型对象属性是相通的
console.log(huawei.nam) //输出张三
//类
class phone2{
static name ="li"
static change(){}
}
let xioa = new phone()
console.log(xioa.name) //输出undefined
console.log(phone2.name) //输出li
构造函数继承
function Phone(brand) {
this.brand = brand
}
function smartPhone(brand,color){
// 这里的this就是把smartphone这个构造函数里面的this指向,替换到phone构造函数里面的this指向中。
Phone.call(this,brand)
this.color =color
}
//设置子级构造函数原型
smartPhone.prototype = new Phone
类继承
class phone{
constructor(brand){
this.brand = brand
}
cal(){}
}
class smartphone extends phone{
constructor(brand,color){
super(brand)
this.color= color
}
cal(){console.log} //重写父类的方法
}
Class的get和set
class Phone{
get price(){return 666} // get 方法
set pric(money){console.log("zhengchang")}
}
let xiao = new Phone()
console.log(xiao.price) //输出666
xiao.pric = "500"
数值扩展
- Number.EPSILON 表示最小精度,可以用于浮点数的比较 ((0.1+0.2) - 0.3) < Number.EPSILON,如果小于就相等
- 0b1010 其中0b表示二进制。0o77 其中0o表示八进制
- Number.isFinite() 检测一个数值是否为有限数
- Number.isNan()检测一个数值是否为NaN
- Number.parseInt(‘123456aaa’)输出123456。 Number.parseFloat() 将字符串转换为数字
- Number.isInterger()判断一个数是否为整数
- Math.trunc()将数字的小数部分抹掉
- Math.sign() 判断一个数是正数,负数还是0
对象方法的扩展
- Object.is(a1,a2)判断两个值是否完全相等
- Object.assign(a1,a2) 对象的合并 属性相同a2覆盖a1的,属性不同就和并
- Object.setPrototypeOf(a1,name)设置原型对象 a1是要设置的对象 ,name是原型对象即__proto__里面的对象
- Object.getPrototypeOf(a1) 获取原型对象
ES6模块化语法
- export命令用于规定模块的对外接口
- import命令用于输入其他模块提供的功能
//(1)分别暴露
export let sch = 'libai' //对外暴露变量
export function tec(){console.log('111')} //对外暴露方法
//(2)统一暴露
let sch = 'libai'
function tec(){console.log('111')}
export {sch,tec}
//(3)默认暴露
export default{
sch: 'libai',
tec: function(){}
}
在script标签中引入
<body>
<!--type="module"-->
<script type="module">
//(1)通用导入方式,无论哪种暴露都可以用通用方式导入
import * as m1 from './1.js' //将对外暴露的数据存入m1中
//(2.1)解构赋值形式(分别暴露,统一暴露)
import {sch,tec} from './1.js'
//(2.2)解构赋值形式(默认暴露)
import {default as m3} from './1.js'
//(3)简便形式(只针对默认暴露)
import m3 from './1.js'
//如果是分别暴露或统一暴露
console.log(m1.sch)
//如果是默认暴露,要加个default
console.log(m1.defaullt.sch)
</script>
</body>
在js文件中引入
import * as m1 from './1.js'
<body>
<!--type="module"-->
<script src="./1.js" type="module"></script>
</body>
babel
- babel是一个javascript编辑器,可以将javascript比较新的语法,转换成浏览能够识别的js语法
- 安装工具babel-cli 命令行,babel-preset-env 转换,browserify打包
import $ from 'jquery' //导入jquery包
ES7
- Array.prototype.includes 用来检测数组中是否包含某个元素,返回布尔值
- ** 是指数操作符,用来实现幂运算,功能与Math.pow结果相同
const a = ['aaa','bbb','ccc']
console.log(a.includes('aaa')) //返回true
console.log(2**6)//输出64
ES8
对象方法的扩展
- Object.keys() 方法返回对象的所有键
- Object.values() 方法返回对象的所有值
- Object.entries() 返回返回对象键值对的集合
- Object.getOwnPropertyDescriptors() 返回对象属性的描述对象啊
const sch = {
name: "shang",
age: "16"
}
Object.keys(sch)
const m =new Map(Object.entries(sch)) // 将对象转换成map
ES9
扩展运算符和rest参数
function conn ({host,port,...use}){
console.log(host)
console.log(use)
}
const a1 ={q:'111'}
const b1 = {e:'222'}
const c1={...a1,...b1}
正则扩展
命名捕获分组
let str = '<a href ="http://www.baidu.com">aaa</a>'
// 通配(.*)
const reg =/<a href ="(.*)">(.*)<\/a>/
const result = reg.exec(str)
console.log(result[2]) //输出aaa
const reg2 =/<a href ="(?<url>.*)">(?<text>.*)<\/a>/
const result2 = reg.exec(str)
// 命名捕获分组 ?<>
console.log(result2.groups.text) //输出aaa
反向断言
let str ='js7123fff666aaa'
// 正向断言
const reg = /\d+(?=a)/
// 反向断言
const reg =/(?<=f)\d+/
dotAll模式
//加了s后.就能匹配任意字符,不加s那么.不能匹配换行符
const reg /./s
ES10
对象方法扩展
- Object.fromEntries()用来创建一个对象,参数是一个二维数组或map
字符串扩展
- trimStart() ,trimEnd() 去空格
数组扩展
- flat() 将多维数组转化为低维数组
- flatMap()
const aa = ['1','2',['3','4']]
console.log(aa.flat()) //['1','2','3','4']
Symbol扩展
- Symbol.prototype.description
let s = Symbol('aaa')
console.log(s.description) //输出aaa
ES11
私有属性
class Person{
// 公有属性
name;
//私有属性
#age;
constructor(name,age){
this.name = name;
this.#age =age;
}
}
promise扩展
- Promise.allSettled([a1,a2])接收一个promise数组,返回一个promise对象,返回结果永远是成功状态
- Promise.all([a1,a2]) ,如果a1,a2都成功,才成功
字符串扩展
- String.prototype.mathAll 得到正则批量匹配的结果
可选链操作符
- ?. 是可选链操作符
cosnt per = function(conf){
const aa =conf.db.host //此时如果conf没传值即per() 则会报错
const aa =conf?.db?.host //此时如果conf没传值即per() 不会报错,输出undefined
}
per()
动态import
- 动态import可以实现按需加载
export hello(){console.log("666")}
//动态import
import('./hello.js).then(module =>{
//module 成功时返回的就是暴露的对象
module.hello() //输出666
})
BigInt类型
//大整形
let n = 45n
//函数
let a =123
console.log(BigInt(a))
绝对全局对象
- globalThis始终指向全局对象