ES6
兄弟们给个赞呗!!!
一、块级绑定
var 存在三个问题
1.允许重复的变量声明;容易导致数据被覆盖
2.变量提升:怪异数据访问、闭包问题
3.全局变量挂载到全局对象:全局对象成员污染问题
let 块级作用域
块级作用域:代码执行的时候遇见花括号就是一个块级作用域
1.当前作用域下,不可重复再声明
2.没有变量提升(底层实现上,let声明的变量还是会有提升的,但是,提升后会将其放到“暂时性死区”,所以访问时会报错的。)
3.声明的对象不会挂载到全局对象(块级作用域嘛)
!!!注意:循环中使用let 的循环变量,会特殊处理,每次进入循环会开启一个新的作用域,比如i<10 则有10个作用域,10个值,并且在循环之后会将let生命的i销毁掉!!!
for(var i = 0; i<2; i++ ){
console.log(i)
}
console.log(i)// 0 1 2
• for(let j = 0; j<2; i++ ){
• console.log(j)
• }
• console.log(j)//0 1 报错 销毁掉了
let arr = [];
for(let i=0; i<5;i++)
{
arr[i] = function (){
console.log(i);
}
}
for(let i=0; i<arr.length;i++)
{
a[i]();
}
const 块级作用域必须赋值
基本与let相同
(本质是变量指向的那个内存地址不改动)
1.常量必须在声明时赋值,且不可以重新赋值
!!!注意!!!如果说是复杂数据类型如数组,对象只要指针指向的地址不变即可,给对象新的属性也是可以的
2.当前作用域下,不可重复再声明
3.没有变量提升
4.声明的对象不会挂载到全局对象(块级作用域嘛)
!!!注意!!!普通for循环不可以用const
二、模板字符串
模板字符串就是这个东东 ``
它可以识别html标签和其中的空格,另外这是最简单的用法还有就是利用函数来实现,这个方法个人感觉用的比较少,这里就不做介绍了,如果想要拓展的话可以了解一下]
//模板字符串的写法
var template=`${name}是一个${type}`;
console.log(template);//小俊是一个大帅哥
var templateStr=`<div>
<p>${name}是一个${type}</p>
</div>`;
console.log(templateStr);
// <div>
// <p>小俊是一个大帅哥</p>
// </div>
//使得代码的结构可读性更强
三、函数
参数默认值
从字面上来理解,就是给函数入参弄一个默认值,有一些经常要用到的固定值就在这里写上,但不是一层不变的。
例如
function add(a=1,b=3,c=2){
return a+b+c
}
this.add(2,4,5)//如果传入值的话就不使用默认值!!!
this.add(null,4,5)//切记传null的话也是相当于传了一个值 上边返回 9(0+4+5)
this.add(null,undefined,5)//这样的话就是b没有传 返回的就是 8(0+3+5)
剩余参数
它的用途主要来替代原本函数的arguments实参集(因为有时候形参名与arguments混用不方便),功能类似,但是,他的注意点和写法主要是如下
function rename(...args)//这个args名字随便起 此时是一个数字数组 [1,2,3]
{
let sum = 0
for(let i = 0;i<args.length;i++)
{
sum = sum+args[i]
}
return sum
}
this.rename(1,2,3)
//而且每一个函数里只能用一次剩余参数,多了的话程序跟不识别不了
//而且...args必须放到入参的最后边 不可以放到中间(a,b,...args,c)这样不可以的
箭头函数
这个部分是ES6的精髓,我单独写一篇文章来介绍,请关注我的箭头函数!!!
四、面向对象
面向对象的思想就是 把我们想干的每一件事情都抽象成一个个对象,举个例子,比如我们想盖一个房子,那么这个房子就是一个对象,这个对象有一些属性,比如这个房子的面积,这个房子的位置,这个房子的价格。这个房子还有一些功能,比如居住,那么这个就相当于对象的一些方法,如果使用面向过程的思想来做这件事,那么我们每次盖一个房子,我们都需要设置这个对象的面积,位置,价格,并且会重复性的表述 这个房子有一个居住的功能,这些重复性的工作显然不是我们想做的,如果我们使用面向对象的思想来做这件事情 ,那么我们可以把房子抽象成 一个对象, 所有的房子不管是北京的房子,还是上海的房子,那么他们都有面积,价格,位置这些属性,他们还有一个公共的功能那就是居住,这样的话我们把这些公共的属性和方法写在这个对象的prototype原型之中,把一些私有的属性通过this指向每一个子级别的对象当中去,这样就避免了代码的重复也提高了程序的性能。
类:构造函数的语法糖
传统的构造函数的问题
-
属性和原型方法定义分离,降低了可读性
-
原型成员可以被枚举
-
默认情况下,构造函数仍然可以被当作普通函数使用
类的特点
-
类声明不会被提升,与 let 和 const 一样,存在暂时性死区
-
类中的所有代码均在严格模式下执行
-
类的所有方法都是不可枚举的
-
类的所有方法都无法被当作构造函数使用
-
类的构造器必须使用 new 来调用
类: 的其他书写方式
1.静态成员,static
2.set,get
类:继承
如果两个类A和B,如果可以描述为: B是A,则,A和B形成继承关系。
如果B是A,则:
1.B派生自A
2.A派生B
3.B是A的子类
如果A是B的父类,则B类会自动拥有A的所有实例成员,有且只有一个父类。
新的关键子 extends 用于定义子类继承于哪一个父类,
super直接调用,1.表示父类构造函数。注意在子类如果写了constructor的话,constructor中必须要调用super,而且是要第一行。2.可以在子类print方法中使用super.print()调用父类的同名方法
如果子类不写constructor构造器,则相当于调用父类的constructor构造器。
冷知识:如果你你建立了一个父类,则不能直接调用父类创建实例
比如你有一个动物父类,狗子类,则不能创建动物实例,new.target=>new Anmail
五、解构
对象解构
定义:使用ES6语法,将一个对象或者数组的某个属性提取到某个变量中
const user = {
name: "kevin",
age: 11
}
let {name,age,abc} = user
console.log(name,age,abc)//kevin 11 undefined
结构中使用默认值
如果对象或数组中没有同名变量或属性会变成undefined
避免undefined使用这个
{同名变量 = 默认值}
const user = {
name: "kevin",
age: 11
}
let {name,age,abc="kk"} = user
console.log(name,age,abc)//kevin 11 kk
非同名属性解构
const user = {
name: "kevin",
age: 11,
address:{
provice: "成都"
}
}
let {name,address:{provice}} = user
console.log(name,provice)//kevin 成都
数组解构
与对像同理
const numbers = ['a','b','c','d']
const [p1,,,p4] = numbers
console.log(p1,p2)//a d
const numbers = ['a','b','c',[1,2,3,4]]
const [,,,[ , , n]] = numbers
console.log(n)//3
补充:
结构剩余项
const obg = {
name:'213'
adress: {
provice: "cchengdu"
jidao: "chunxilu"
}
}
let {name,...onj} = obg
//输出就是name 和一个obg中除name剩余的对象
交换两个值
let a = 1 ,let b = 2
[a,b]=[b,a]
参数解构
在函数声明时候形参处解构