JavaScript Es6-Es11 新语法特性
JavaScript Es6-Es11 新语法特性
EchoES6
ES6 语法简洁 各个框架都需要用到ES6
1,ES5
1.1介绍
ES5 除了正常运行模式(又称为混杂模式),还添加了第二种运行模式:”严格模式“(strict mode)。
严格模式顾名思义,就是使 JavaScript 在更严格的语法条件下运行。
1.2作用
- 消除 JavaScript 语法的一些不合理、不严谨之处,减少一些怪异行为
- 消除代码运行的一些不安全之处,保证代码运行的安全
- 为未来新版本的 JavaScript 做好铺垫
1.3使用
- **在全局或函数的第一条语句定义为: **
'use strict'
- 如果浏览器不支持,只解析为一条简单的语句, 没有任何副作用
1
2
3
4
5
6
7
8
9
10// 全局使用严格模式
'use strict';
girl = '迪丽热巴';
// 函数中使用严格模式
function main(){
'use strict';
boy = '吴亦凡';
}
main();
1.4语法和行为改变
- 必须用 var 声明变量,不允许使用未声明的变量
- 禁止自定义的函数中的 this 指向 window
- 创建 eval 作用域
- 对象不能有重名的属性(Chrome 已经修复了这个 Bug,IE 还会出现)
- 函数不能有重复的形参
- 新增一些保留字, 如: implements interface private protected public
1.5Object 扩展方法
Object.create(prototype, [descriptors])
Object.create 方法可以以指定对象为原型创建新的对象,同时可以为新的对象设置属性, 并对属性进行描述
- value : 指定值
- writable : 标识当前属性值是否是可修改的, 默认为 false
- configurable:标识当前属性是否可以被删除 默认为 false
- enumerable:标识当前属性是否能用for in 枚举 默认为 false
- get: 当获取当前属性时的回调函数
- set: 当设置当前属性时
1 | //创建一个汽车的对象 |
- Object.defineProperties(object, descriptors)
直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
- object 要操作的对象
- descriptors 属性描述
- get 作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。
- set 作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。
1 | // 定义对象 |
小练习
向对象里面添加属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<script type="text/javascript">
let banji={
name:'计算机一班',
scores:[
{name:'张三',cj:100},
{name:'张四',cj:90},
{name:'张五',cj:80},
{name:'张六',cj:70},
]
}
//为班级添加一个新的属性 总成绩 和平均成绩
Object.defineProperties(banji,{
pjcj:{
get:function(){
let zongcj=0;
for(let i=0;i<this.scores.length;i++){
zongcj+=this.scores[i].cj;
}
return zongcj;
}
}
});
console.log(banji.pjcj);
</script>call、apply 和 bind
call 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
1
2
3
4
5
6
7
8
9
10
11
12//函数的普通的调用的方法
function add(a,b,c){
console.log(this);//this指向的是window
console.log(a+b+c);
}
//普通调用
add(10,29,10);
//使用call调用
add.call({},1,2,3);//使用call来调用函数 第一个{} 是代表的是this指向的值 后面放参数apply 方法调用一个具有给定 this 值的函数,以及作为一个数组(或类似数组对象)提供的参数
就是修改函数this的值
1
apply.apply({name:'dd'},[1,2,3]);
bind 同 call 相似,不过该方法会返回一个新的函数,而不会立即执行
**会返回一个新的函数 **
1 | function main(){ |
- 函数和方法
function 在对象的内部被称为 方法
function 在对象的外部被称为 函数
2.ES6使用
2.1 变量的声明
ES6的变量的声明 支持的格式形式 比较多下面的都可以
字母数字下划线 首字母不能使用数字 严格区分大小写 不能使用关键字 驼峰命名法
1 | let a; |
2.2 let 关键字
变量的声明不能重复
1 | let a=100; |
**块级作用域 只能在当前的块级作用域里面使用 **
1 | { |
不存在变量提升
1 | alert(b);//使用var 声明的变量会有变量提升 |
不影响作用域链 使用let声明的不影响作用域链
1 | functon fn(){ |
2.3 const 关键字
const 用来声明一个常量 (值不变的量)
格式
**声明的时候一定要赋初始值 **1
const Name='UZI';
声明的时候一定要赋初始值
常量的名称一般会大写(潜规则)
不允许重复声明 不允许重复赋值
块级作用域
关于数组和对象的元素的修改
对于数组来说 修改里面的值是不会报错的 因为存的是数据所指向的地址
同样的对于对象来说这样修改对象的属性也是可以的 和数组一样存的也是所指向的地址
1
2
3const TEAM=['A','B'];
TEAM.push('SSS');
//这样的是允许的1
2
3
4const big={
name:'sddd'
}
big.name='aaa'
2.4 变量的解构赋值
ES6 允许按照一定的模式从数组和对象中提取值,对变量进行赋值 这被称为解构赋值
使用方式
z l w 的值是和arr 里面的三个值是一一对应的
1
2
3const arr=['张三','李四','王五'];
let [z,l,w]=arr;
console.log(z,l,w);对象的解构赋值
1
2
3
4
5
6
7
8const star={
name:'于谦',
tags:['抽烟','喝酒','烫头'],
say:function(){
console.log('说相声');
}
}
let {name,tags:[c,h,t],say}=srar;
2.5 模板字符串
增强版的字符串 在原生的js中 使用单引号和双引号来声明字符串
在ES6中 允许我们使用 反引号来声明字符串
字符串中可以出现换行符
原生的js需要使用+ 把所有的内容连接起来 才不会报错 ES6 直接``里面写就可以
1
2
3
4
5let str=`<ul>
<li>张三</li>
<li>张三</li>
<li>张三</li>
</ul>`字符串中进行变量的拼接
直接在字符串的中间 加上${变量名}
1
2let one='张三';
let two=`做坏事,${one} 这好吗`;
2.6 简化的对象的写法
1 | let name='张三'; |
2.7 箭头函数
ES6 里面允许我们使用箭头函数来代替function
- 声明格式
let 函数名=(形式参数)=>{ 函数体 }1
2
3let add=(a,b,c)=>{
return a+b+c;
} - 调用
1
2
3
4
5
6// 直接调用
add(1,2,3);
//使用call
add.call({},1,2,3);
//使用apply
add.apply({},[1,2,3]);
2.8 箭头函数的特点
- 箭头函数的this 是静态的 它是指向外层函数作用域的this的值
1
2
3
4let getName=()=>{
console.log(this);
}
//这个this是指向它外层函数的this的值 在这个里面指向的是window - 箭头函数不能作为构造函数使用
1
2
3
4const getname=()=>{}
//这样是万万不可的
let name=new getanme(); - 不能使用arguments
arguments 里面放的是所有的实参
2.9 箭头函数的简写
当形参有且只有一个的时候 小括号可以不写
1 | let pow1=(num)=>{return num*num}; |
当代体只有一句的时候花括号也可以不写 return 也可以不写 默认返回的就是表达式的结果
1 | let pow1=(num)=>{return num*num}; |
如果回调与this相关 的 就不能使用箭头函数
如果回调与this无关的话 建议使用箭头函数
- 定时器
- **数组方法的回调函数 **
2.10 参数的默认值
在ES6 中是允许使用参数默认值的
1 | function fu(a,b,c=10){ |
**与结解构赋值联合使用 **
1 | function fn(a,b,c){ |
2.11 rest 参数
arguments 参数就是我们传递入函数的参数的值
1 | function fun(){ |
使用rest函数
书写的格式是 … 名称
但是如果我们传递多个参数 rest函数只能是写在最后一个 否则会报错出现问题
rest 函数会把你传入的参数形成一个数组
1 | function sumRest (...m) { |
spread 扩展运算符 可以对数组进行展开
1 | let arr=['d','s','d']; |
2.12 rest 参数的应用
- 数组的合并
1
2
3
4const arr=[1,2,3];
const arr3=[4,5,6];
//把两个数组合并为一个数组
const shuzu=[...arr,...arr2]; - 数组的克隆
1
2
3
4const arr=[1,2,3];
//数组的克隆
const arr2=[...arr,122];
//数组后面也可以添加新的元素 - 伪数组转化成为真的数组
1
2
3const divs=document.getelementbytagbane('div');
//
const reslist=[...divs];
2.13 symbol 数据类型
symbol 是JavaScript 里面的一种独特的数据类型 类似于字符串 但是值不能改变
Symbol 类型的值不能与其他类型的值进行运算
创建symbol
1
2
3let s1=Symbol();
//直接调用Symbol 就可以
let s2=Symbol('品牌');Symbol 的合理的使用的方法就是作为创建对象的属性的值来使用 单纯的使用没有价值
1
2
3
4
5
6
7
8
9
10
11
12let game={
up: '上升'
};
//为game添加新的属性
let methed={
down:Symbol();
}
//添加down属性
game[methed.down]=function(){
}
//调用
game[methed.down]();Symbol 在函数的内部添加方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21let math={
up:Symbol(),
down:Symbol()
}
let game={
name='俄罗斯',
gameover:function(){
alert('游戏结束');
}
//添加新的方法
[math.up]:function(){
aelrt('ddd');
}
//添加新的方法二
[str]:function(){
alert('dddddddd');
}
}Symbol 的内部值
除了定义自己使用的 Symbol 值以外,ES6 还提供了11个内置的Symbol值,指向语言内部使用的方法。
Symbol.hasInstance 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法 Symbol.isConcatSpreadable 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。 Symbol. unscopables 该对象指定了使用with关键字时,哪些属性会被with环境排除。 Symbol.match 当执行str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。 Symbol.replace 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。 Symbol.search 当该对象被str. search (myObject)方法调用时,会返回该方法的返回值。 Symbol.split 当该对象被str. split (myObject)方法调用时,会返回该方法的返回值。 Symbol.iterator 对象进行for…of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器 Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 Symbol. toStringTag 在该对象上面调用toString方法时,返回该方法的返回值 Symbol.species 创建衍生对象时,会使用该属性
2.14 迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
\1) ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
\2) 原生具备iterator接口的数据(可用for of遍历)
Array Arguments ** Set Map String TypedArray NodeList**
fior in 和 for of
for in 遍历后得到的结果是数组元素的下标
for of 遍历后得到的结果是元素的值
1
2
3
4
5
6
7
8
9const list=['a','b','c'];
for(let i in list){
console.log(i);
}
//for of
for(let i of list){
console.log(i)
}
2.15 类内部属性的getter 和 setter (了解)
get 和 set 可以让我们在获取和设置 属性的时候 能有反馈 让程序拥有更多的可能性
1 | class phone{ |
2.16 ES6 的数值扩展
**二进制 ob开头 ob1111 **
八进制 0o开头 0o6666
**十进制 **
十六进制 ox开头 oxfff
1.检查一个数是不是有限数
1 | Number.isFiniter(10);//检测10是不是一个有限数 |
**2.检测一个数是不是NaN (NaN 就是是不是数字的意思) **
1 | Number.isNaN(NaN); |
3.parseInt() 字符串转换为数字
1 | Nmuber.parseInt('1112121'); |
4.Math.trunc() 抹除数字的小数部分
1 | Math.trunc(3.123); |
5.isInteger() 检查一个数是不是整数
1 | NUmber.isinteger(2.1) |
6.数字的幂运算
1 | 3**n |
2.17 Set 集合
Set 只允许存放不同的值 我们可以把数组转换成集合来达到数组去重对效果
- 声明一个集合
1
2const s2=new Set();
const s1=new Set([1,2,3,4]);
集合的常用方法
1 | //声明集合 |
集合练习
对象中的扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
数组转集合
利用集合中不允许有同样的值的这个特性来达到数组去重的效果
1
2
3
4
5
6//集合转数组
const arr=['aaa','bbb','ccc','aaa','ddd'];
const s=new Set(arr);
//集合转数组
const math=[...s];
console.log(math);
2.18 Map
本身是地图的意思 但是也是有映射的意思 键值对
声明map
1
const m=new Map();
添加元素 元素,set( 键,值 )
键可以是字符串也可以是对象
1
2m.set('name','张三');
m.set({},'ahahhahah');获取元素
1
2
3const m=new Map();
m.set('name','张三');
console.log(m.get('name'));删除元素
1
m.dlete('name');
检测
1
m.has('name');
元素个数
1
m.size();
清空
1
m.clear();
Map的主要作用是用作缓存
3,ES6
3.1 class介绍与类的创建
类似于java的类 通过class可以创建类
语法
**class 类名{ **
** //构造方法**
** **constructor( 属性1, 属性2){
** **this.属性1=属性1;
** **this.属性2=属性2;
** **}
//方法
coll( 形式参数){
** **方法体;
** **}
}
1
2
3
4
5
6
7
8
9
10
11class Phone{
constructor(name,price) {
this.name=name;
this.price=price;
}
call(person){
console.log(`我可以给 ${person} 打电话`);
}
}
let xiaomi=new Phone('小米',1999);
xiaomi.call('张三');注意事项
- 构造方法不是必须的
- 构造方法只能写一个 constructor 只能写一个
3.2 静态成员
静态成员 属于类 而 不属于实例对象
1 | class Phone{ |
3.3 继承
class 子类 extends 父类{
** **子类的属性和方法
}
注意 如果要继承父类的属性的话 在construction 里面也写上父类的属性
1 | <script type="text/javascript"> |
3.4 类内部的set 和 get
set 和 get 可以让我们对代码的控制更加的灵活和多样
1 | class phone{ |
3.5 ES6 的数值扩展
**二进制 ob开头 ob1111 **
八进制 0o开头 0o6666
**十进制 **
十六进制 ox开头 oxfff
1.检查一个数是不是有限数
1 | Number.isFiniter(10);//检测10是不是一个有限数 |
**2.检测一个数是不是NaN (NaN 就是是不是数字的意思) **
1 | Number.isNaN(NaN); |
3.parseInt() 字符串转换为数字
1 | Nmuber.parseInt('1112121'); |
4.Math.trunc() 抹除数字的小数部分
1 | Math.trunc(3.123); |
5.isInteger() 检查一个数是不是整数
1 | NUmber.isinteger(2.1) |
6.数字的幂运算
1 | 3**n |
3.6 对象的扩展
判断两个值是否相等
object.is(数值1,数值2)
1
2
3let n=100;
let n2-200;
console.log(Object.is(n1,n2));对象的合并
Object.assign( 对象A ,对象B)
把B对象的合并到A对象
返回的是原对象
1
2
3
4
5
6
7
8const a={
name:'dddd'
}
const b={
aa:['北京','上海']
}
const c=Object.assign(a,b);
console.log(c);对象的合并主要是用在项目的配置上
3.7 数据的浅拷贝
如果复制出来的新的数据 发生了变化 原数据也会发生变化叫做浅拷贝
直接复制
arr2的数据改变 arr1的数据也会跟着改变
1
2
3let arr=[1,2,3];
const arr2=arr;
arr2[1]=0;数组
- **concat() **
concat() 方法用于连接两个或多个数组。
concat() 方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。
1
2
3let arr=[1,2,3];
let arr2=[].concat(arr);
arr2[1]=2222;- slice(a,b)
slice 是截取参数是数组的下标 从a开始到b结束
1
2let arr=[1,2,3,4];
let arr2=arr.slice(0,1);- 扩展运算符
1
let arr=[...oldarr];
- **concat() **
对象
assign: 是object中的一个成员方法 它的作用是能够进行对象的合并1
2
3
4
5
6
7const school={
name:'wyq',
pos:['武汉']
}
const newSchool=Object.assign({},school);
newSchool.name='dddddddddd';
console.log(newSchool.name,school.name);
3.8 JSON 实现深拷贝
stringify 能将js对象转换为json格式的字符串
**parse 能将json 格式的字符串转换为js对象 **