ES6是ECMAScript第六版
ES6的内容包括:
1.声明变量的方法(1et和const)
2.变量的解构赋值
3.扩展运算符
4.数据劫持箭头函数
5. Set Map
6. 数组对象数值的扩展
7. Promise对象
8. Generator 函数
let和const
let声明的变量只在所处于的块级有效
if (true) {
let a = 1;
}
console.log(a) // a is not defined
使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
let不存在变量提升
console.log(a); // a is not defined
let a = 20;
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); //2
arr[1](); //2
//因为i是全局变量
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); //0
arr[1](); //1
//因为每次循环都会产生一个块级做作用域
let总结
let关键字就是用来声明变量的
使用let关键字声明的变量具有块级作用域
在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
防止循环变量变成全局变量
使用let关键字声明的变量没有变量提升
使用let关键字声明的变量具有暂时性死区特性
const
具有块级作用域
if (true) {
const a = 1;
}
console.log(a) // a is not defined
常量赋值后,值不能修改
const a = 10;
a = 100; // Assignment to constant variable.
const总结
const声明的变量是一个常量
既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
声明 const时候必须要给定值
let、const、var 的区别
- 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
解构赋值
在ES6中按照一定的模式 从数组中提取数值 对对应的变量进 行赋值的操作就叫做解构赋值
let [a, b, c,d] = [1, 2, 3];
console.log(a)//1
console.log(b)//2
console.log(c)//3
console.log(d)//undefined
对象解构
let person = { name: 'zhangsan', age: 20 };
let { name, age } = person;
console.log(name); // 'zhangsan'
console.log(age); // 20
let {name: myName, age: myAge} = person; // myName myAge
console.log(myName); // 'zhangsan'
console.log(myAge); // 20
总结
- 解构赋值就是把数据结构分解,然后给变量进行赋值
- 如果结构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
- 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
- 利用解构赋值能够让我们方便的去取对象中的属性跟方法
扩展运算符(…)
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
let ary = [1, 2, 3];
console.log(...ary); // 1 2 3,相当于下面的代码
扩展运算符可以应用于合并数组
// 方法一
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [...ary1, ...ary2];
// 方法二
ary1.push(...ary2);
var arr = [100, 200, 300];
var arr1 = arr;
//直接赋值修改了原数组的值arr1里 面的值也会发生改变因为他们指向同一块内存空间
arr[1] = 20;
console.log(arr1); // [100, 20, 300]
var arr = [100, 200, 300];
//这是是使用扩展运算符就是 一个一个加到新数组里面去所以即便原数组元素发生变化也不会 影响新数组
var arr2 = [...arr];
arr[0] = 10;
console.log(arr2);
对象的扩展
对象属性的简单赋值方式:可以将变量名直接放进对象中, 解析的时候 将变量名解析为属性名 变量值解析为属性值
对象方法的简单赋值 可以省略function关键字
var stu= {
study() {}
}
super关键字
作用:指向当前对象的原型对象
注意点: 1. 只能在对象的方法中使用 在其他地方使用都会报错
2. 只能在对象方法的简写方式中使用
var obj={
name:'zs',
age:18,
gender:'男',
//报错 super' keyword unexpected here
//meth:function(){
//console.log("我叫" +this.name + "我想" + super.sleep);
//}
meth(){
console.log("我叫" +this.name + "我想" + super.sleep);
}
}
obj.__proto__={
sleep:'碎觉'
}
新增的API
Object.is()
它用来比较两个值是否严格相等 用法基本上跟严格相等(===) 一样 只是在-0 和+0 还有NaN的判断上面不一样
console.log(Object.is('name','name')); //true
console.log(Object.is('123',123)); //false
console.log(Object.is(NaN,NaN)); //true
console.log(Object.is(0,0)); //true
console.log(Object.is(+0,-0)); //false
Object.assign()
Object.assign()用于对象的合并
参数:
参数1 : 目标对象
参数2 : 需要被合并的对象
var obj1={a:1};
var obj2={b:2};
var obj3={c:3};
var newobj1=Object.assign(obj1,obj2,obj3)
//注意点1:返回值是传入的第一个目标对象 会把所有的对象合并上去时候再返回
console.log(newobj1); //{a: 1, b: 2, c: 3}
console.log(newobj1==obj1); //true
//注意点2:第一个参数必须是对象 如果不是对象 就会把它转为对象
var newobj2=Object.assign("",obj2,obj3)
console.log(newobj2); //String {"", b: 2, c: 3, length: 0}
//注意点3:如果是undefined或者null 没办法转为对象 name就会报错
var newobj3=Object.assign(null,obj2,obj3)
console.log(newobj2); // Cannot convert undefined or null to object
var obj1={a:1,b:10};
var obj2={b:2};
var obj3={c:3};
//注意点4:如果需要合并的多个对象里面有同名的属性 后面的属性就会对前面的进行覆盖
//var newobj1=Object.assign(obj1,obj2,obj3)
//console.log(newobj1); //{a: 1, b: 2, c: 3}
//注意点5:如果undefined和null不是第一个参数 就不会报错 第一个参数返回
var newobj2=Object.assign(obj1,null,obj3)
console.log(newobj2);
//注意点6:assign方法是浅拷贝 不是深拷贝
//浅拷贝:简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝
//深拷贝:在内存中重新创建一个引用类型,复制的两者不会相互影响
var obj={
a:{b:10}
}
var s=Object.assign({},obj);
console.log(s);
obj.a.b=11;
console.log(s.a);
console.log(obj.a);
总结注意点:
- 该方法的返回值一定传入的第一个参数, 会把后面的参数全都合并上去之后返回
- 第一个参数必须是对象 如果是基本数据类型 就转换成对应的包装类返回
- 如果第一个参数是undefined 或者null 因为他们无法转换成对象 那么就会报错
- 如果喝冰的对象里面有同名的属性 那么后面的就会覆盖前面的
- 如果有两个参数 undefined 或者null不作为第一个参数 那么就回原值第一个参数
- Object.assign方法是浅拷贝 不是深拷贝
Object.setPrototypeOf()
设置一个对象的原型对象
var proto = {};
var obj = {
x: 10
};
Object.setPrototypeOf(obj, proto);
proto.y = 20;
proto.z = 40;
console.log(obj.x) // 10
console.log(obj.y) // 20
console.log(obj.z) // 40
///获取对象原型
console.log(Object.getPrototypeOf(obj)); //{y: 20, z: 40}
Object.keys()
是将对象所有的属性名获取到 添加到数组 并返回 返回的是一个数组
var obj={
name:'张三',
age:18,
gender:'男'
}
console.log(Object.keys(obj)) //["name", "age", "gender"]
//Object.values() 获取属性值
//是将对象所有的属性值遍历 然后返回一个数组
console.log(Object.values(obj))
class关键字
传统构造函数
function Stu(name, age) {
this.name = name;
this.age = age;
}
Stu.prototype.work = function() {
return this.name + ',' + this.age;
}
console.log(Stu.prototype);
//可以被当做普通的函数进行调用
console.log(Stu());
//可以遍历
for (var key in Stu.prototype) {
console.log(key);
}
缺点:
- 构造函数和原型方法及属性分离 不便于维护 降低可读性
- 原型对象可以被遍历修改
- 默认情况下构造函数可以被当做普通的函数进行调用 功能性不明确
- 原型中的方法也可以作为构造函数来用
class就是一颗语法糖 他的本质还是函数 而且是ES5里面的函数封装而成的
//class的用法很let和const一样 都有暂时性死区 必须先定义 再使用
var stu = new Stu('张三', '男');
console.log(stu.toString()); //报错
class Stu {
constructor(name, sex) {
this.name = name;
this.sex = sex;
}
toString() {
return this.name + "," + this.sex;
}
}