- let 和 const 声明:引入了块级作用域的变量声明方式,let 声明的变量只在其所在的块级作用域内有效,而 const 声明的变量是只读的。
- 箭头函数:提供了更简洁的函数定义方式,并且自动绑定 this 上下文。
- 模板字符串:使用反引号(`)来定义字符串,可以进行多行字符串的定义,并且支持插入变量和表达式。
- 解构赋值:允许从数组或对象中提取值,并将其赋值给变量。
- 默认参数:函数可以定义默认参数值,当参数未传递时使用默认值。
- 展开运算符:用于将数组或对象展开为单个元素或属性。
- 类和继承:引入了类的概念,支持面向对象编程的特性,如继承、方法定义等。
- Promise:用于处理异步操作,提供了更优雅的异步编程方式。
- 模块化:支持使用模块来组织代码,通过 export 和 import 关键字实现模块的导出和导入。
- 新的对象属性和方法:如 Object.assign ()、Object.entries ()、Object.values () 等,提供了更方便的对象操作方法。
class
extends super
//1.类的定义class Person{//2.类的构造方法/*** 1.传参调用构造函数* 2.不传参调用默认构造函数* 3.一个类只有一个构造方法*/constructor(name,age){this.name=namethis._age=age}//3.类的实例方法say(){console.log("hello",this.name);}//4.类的访问器方法get age(){return this._age;}set age(val){this._age=val}//5.类的静态方法static before(){console.log("创建了");}}//类的继承class Stu extends Person{constructor(name,age,sno){// 1.继承父类属性 使用this之前必须调用super()super(name,age)this.sno=sno}//2.重写父类方法say(){super.say()console.log("子类");}}let stu=new Stu("lxy","22","123893478923")//方法是定义在prototype上console.log(stu.age);Person.before()
对象
继承内置类
// 1.继承内置类class MyArray extends Array{//重写toString方法toString(){return 'MyArray'+super.toString()}}let arr1=new Array(1,2,3)let arr = new MyArray(1,2,3)console.log(arr1.toString());// 1,2,3console.log(arr.toString())// MyArray,1,2,3
类的混入
实现多继承
//2.类的混入//js是单继承,只能继承一个父类,但是可以通过混入的方式实现多继承class Person{constructor(name){this.name=name}sayName(){console.log(this.name)}}function mixin(c){return class extends c{eating(){console.log("eating") }}}let newClass=mixin(Person)let obj=new newClass('obj')console.log(obj.name)// mixin
多态
传统面向对象的多态
- 有继承
- 有重写
- 父类引用指向子类对象
js多态
不用数据类型执行同一操作,结果不同
对象字面量增强
- 属性简写
- 方法简写
- 计算属性名
//1.属性简写let name='obj'let key=18let obj={name,//属性简写[key]:'obj2',//计算属性名say(){//方法简写console.log('say')}}
解构
- 对象解构
- 数组解构
常用于函数参数解构
//1.对象解构let obj={name:'obj',age:18,sno:123}let {name,age,sno:no="7838"}=objconsole.log(name,age)//obj 18;//2.数组解构let arr=[1,2,3]let [a,b,c]=arr
let [a,...newArr] = arr//解构一个元素,剩下的放到数组中
let [,,c]=arr//解构后面的元素
let [a,b,c,d=0]=arr//解构默认值console.log(a,b,c)//1 2 3
let const
新增定义变量的关键字
用法
在用法上,var和let 的用法类似,用于定义变量
const 常用于声明常量,其值不能修改,但是如果传递的是引用类型,引用对象内部属性可以修改
作用域提升
var 声明的变量存在作用域提升,可以在声明之前访问
let const 声明的变量不能在声明之前访问,报错
这个区域称为暂时性死区
console.log(name);//undefinedvar name='name';console.log(age);//ReferenceError: Cannot access 'age' before initializationconsole.log(a);//ReferenceError: Cannot access 'a' before initializationlet age=18;const a=1;
在代码编译期间,变量与函数的声明会存放在VO
变量对象中,在es6中是VE
变量环境
var声明的变量会存放到GO
,所以提前访问是undefined
但是let const
不会在代码编译期间存放到GO
中吗??
不是
let const 声明的变量会在代码编译期间创建只是不能访问
与window的关系
在全局使用var声明变量,实际会在window上添加属性
let /const 不会在window上添加属性,那么变量是保存在哪里呢??
es5 的执行上下文
每一个执行上下文会关联到一个变量环境variable object
,在源代码中的变量与函数声明会作为属性添加到VO中
es6 的执行上下文
每个执行上下文会关联到一个变量环境variableEnvirable
,代码中的函数与变量声明会作为环境记录添加到VE中
VE没有指定是window对象或者其他,js引擎有自己的实现,v8中通过一个hashmap实现存储
window对象是早期的GO对象,最新的实现是浏览器天机的全局对象,并保持var与window对象的连接
块级作用域
var 情况下 只有
- 函数作用域
- 全局作用域
let const 增加了块级作用域
- 函数作用域
- 全局作用域
- 块级作用域 {}
示例
循环中使用var,只输出3
点击触发函数,在当前函数作用域中不存在i,
向上层作用寻找,对于var来讲{}不产生作用域,因此会找到全局的i
此时i已经执行完毕,值为3
//遍历对象,注册点击事件for(var i=0;i<btns.length;i++){btns[i].onclick=function(){console.log(i);//3}}//立即执行函数改进for(var i=0;i<btns.length;i++){(function(n){btns[i].onclick=function(){console.log(n);}})(i)}
使用let
* why:点击触发函数,当前作用域没有i,向上层作用域寻找,
* 上层作用域是块级作用域{},因此会找到let声明的i,此时i的值为每一次i的值
for(let i=0;i<btns.length;i++){btns[i].onclick=function(){console.log(i);}}
模板字符串
字符串与变量拼接,使用${}
剩余参数
...
收集没有实参的形参,是一个数组
而arguments是一个类数组对象
// 函数剩余参数function tag(a,...b){console.log(a,b);//a=1,b=[2,3,4,5]console.log(arguments);//[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 } }tag(1,2,3,4,5)
symbol
- 新增数据类型,用于创建唯一值
et s1=Symbol();let s2=Symbol("222");let s3=Symbol.for("s3");let s4=Symbol.for("s3");let s5=Symbol.for();console.log(s1,s2,s3);//Symbol() Symbol(222) Symbol(s3)console.log(s3===s4);//trueconsole.log(s1===s5);//falseconsole.log(Symbol.keyFor(s3));//s3
- 应用场景:解决属性名冲突
//1.1 应用场景 解决属性名冲突let obj={};obj.name="obj";obj.name="obj1";console.log(obj);//{name: 'obj1'} 被覆盖let s1=Symbol("name");obj[s1]="objsymbol";console.log(obj.name);//obj1console.log(obj[s1]);//objsymbol
- symbol属性无法遍历得到
console.log(Object.keys(obj));//[ 'name' ] symbol属性无法被遍历console.log(Object.getOwnPropertySymbols(obj));//[ Symbol(name) ] 获取symbol属性
Set
类似数组,但是存储不重复
的值
//2.set -- > 数组//存储不重复的值 可以遍历let set=new Set([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]);console.log(set);//Set(9) { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
weakSet
弱引用,存储对象,不能遍历
let obj={name:"obj"};let obj1={name:"obj1"};let obj2={name:"obj2"};let weakSet=new WeakSet();weakSet.add(obj);weakSet.add(obj1);weakSet.add(obj2);console.log(weakSet);//WeakSet { <items unknown> }
Map
类似对象,存储键值对
et map=new Map([["name","obj"],["age",18],[1,2]]);console.log(map);//Map(3) { 'name' => 'obj', 'age' => 18, 1 => 2 }
weakMap
弱引用,不能遍历,key只能是对象
let obj3={name:"obj3"};let obj4={name:"obj4"};let obj5={name:"obj5"};let weakMap=new WeakMap();weakMap.set(obj3,"obj3");weakMap.set(obj4,"obj4");weakMap.set(obj5,"obj5");// weakMap.set(1,2)console.log(weakMap);//WeakMap { <items unknown> }