一、let和const
// 1.var 声明变量存在变量提升,let和const不存在变量提升
console.log(a) // undefined ==> a已声明还未赋值,默认得到undefined值
console.log(b) // 报错:b is not defined 找不到b这个变量
console.log(c) // 报错:c is not defined 找不到c这个变量
var a = 100;
let b = 10;
const c = 10;
// 2.let和const只能在块作用域里访问
if(1){
var a = 100;
let b = 10;
const c = 1;
}
console.log(a); // 100
console.log(b) // 报错:b is not defined ===> 找不到b这个变量
console.log(c) // 报错:c is not defined ===> 找不到c这个变量
// 3.同一作用域下let和const不能声明同名变量,而var可以
var a = 100;
console.log(a) // 100
var a = 10;
console.log(a) // 10
let a = 100;
let a =10; // 报错:Identifier 'a' has already been declared ===> 标识符a已经被声明了。
// 4.const定义常量,而且不能修改,但是在定义的对象是对象时对象属性值可以改变
const a = 2;
a = 3;
console.log(a) // 报错
const person = {
name:"make",
sex:"男"
}
person.name = 'test'
console.log(person.name) //运行发现控制台没有报错,且person.name被成果更改。这是因为对象是引用类型的, person中保存的仅是对象的指针,而修改对象的属性不会改变对象的指针,所以这种情况就会修改成果。也就是说const定义的引用类型只要指针不发生改变,都是被允许的。
// 接下来我们试着修改一下指针,让person指向一个新对象,最后果然报错
const person = {
name : 'make',
sex : '男'
}
person = {
name : 'test',
sex : '男'
}
console.log(person.name) //控制台报错
// 5.小结
1.var定义的变量,变量提升,没有块的概念,可以跨块访问。
2.let定义的变量,只能在块作用域里访问,不能声明同名变量
3.const用来定义常量,使用时必须初始化(必须赋值),不能声明同名变量,只能在块作用域里访问,而且不能修改,但是在定义的对象是对象属性值时可以改变。
4.他们都不能跨函数访问。
二、Symbol
Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值,不能与其他数据类型进行运算,它是JS中的第七种数据类型,与undefined、null、number、string、boolean、object并列。
三、模板字符串
在ES6之前,处理模板字符串通过“\”和“+”来构建模板 在ES6之后,用${}来界定,用反引号(``)直接敲定
字符串新方法
includes判断字符串是否包含参数字符串,返回boolean值
startWith / endWith,判断字符串是否以参数字符串开头或结尾,返回boolean值。这两个方法可以有第二个参数,一个数字,表示开始查找的位置。
let str = 'blue,red,orange,white';
str.includes('blue') // true
str.startsWith('blue') // true
str.endsWith('blue') // false
//repeat()方法按指定次数返回一个新的字符串。
console.log('hello'.repeat(2)); //'hellohello'
// padStart()/padEnd(),用参数字符串按给定长度从前面或后面补全字符串,返回新字符串。
let arr = 'hell';
console.log(arr.padEnd(5,'o')); //'hello'
console.log(arr.padEnd(6,'o')); //'helloo'
console.log(arr.padEnd(6)); //'hell ',如果没有指定将用空格代替
console.log(arr.padStart(5,'o')); //'ohell'
四、解构表达式
解构赋值是对赋值运算符的扩展。它是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。字符串、以及ES6新增的Map和Set都可以使用解构表达式。
// 1.数组解构
let [a,b,c] = [1,2,3];
console.log(a,b,c) // 1,2,3
let [a,b,c] = [1,,3];
console.log(a,b,c); //1,undefined,3
let [a,,b] = [1,2,3];
console.log(a,b);//1,3
let [a,..b] = [1,2,3]; //...是剩余运算符,表示赋值运算符右边除第一个值外剩余的都赋值给b
console.log(a,b);//1,[2,3]
// 2.对象解构
let obj = {
name:"ren",
age:12,
sex:"male"
}
let {name,age,sex} = obj;
console.log(name,age,sex) // 'ren' 12 'male'
let { name: myName, age: myAge, sex: mySex } = obj; //自定义变量名
console.log(myName, myAge, mySex); //'ren' 12 'male'
五、对象方面
Map和Set Map和Set都属于ES6新增加的对象 Map:Map对象用于保存键值对,任何JS支持的值都可以作为一个键(key)或者一个值(value)。与对象不同的是 1.Object的值只能是字符串或者ES6的Symbol值,而Map可以是任何值 2.Map对象有一个size属性,存储了键值对的个数而Object对象没有任何类似属性
let myMap = new Map([['name','ren'],['age',12]]);
console.log(myMap); //{'name'=>'ren','age'=>12}
myMap.set('sex','male');
console.log(myMap); //{'name'=>'ren','age'=>12,'sex'=>'male'}
console.log(myMap.size); //3
myMap.get('name'); //'ren'
myMap.has('age'); //true
myMap.delete('age'); //true
myMap.has('age'); //false
myMap.get('age'); //undefined
Set 可以理解为后端的Set集合对象 Set对象和Map对象类似,但它存储的不是键值对。类似数组,它的每个元素都是唯一的。
let mySet = new Set([1,2,3]);//里面要传一个数组,否则会报错
console.log(mySet); //{1,2,3}
mySet.add(4);
console.log(mySet); //{1,2,3,4}
mySet.delete(1); //true
mySet.has(1); //false
console.log(mySet); //{2,3,4}
利用Set对象唯一性的特点,可以轻松实现数组的去重
let arr = [1,1,2,3,4,4];
let mySet = new Set(arr);
let newArr = Array.from(mySet);
console.log(newArr); //[1,2,3,4]
六、函数方面
箭头函数
1.相比普通函数,箭头函数更加简洁而
// 普通函数
function add(num){
return num + 10
}
// 箭头函数
const add = (num) => {
return num + 10
}
2.箭头函数不绑定this,会捕获其所在上下文的this,作为自己的this(需要注意的是,箭头函数的外层如果有普通函数,那么箭头函数的this就是这个外层的普通函数的this,箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量)
// 箭头函数外层有普通函数
let obj = {
fn:function(){
console.log('我是普通函数',this === obj) // true
return () => {
console.log('我是箭头函数',this === obj) // true
}
}
}
// 箭头函数外层无普通函数
let obj = {
fn:()=>{
console.log(this === window)
}
}
console.log(obj.fn()) // true
3.箭头函数是匿名函数,不能作为构造函数,不能使用new命令,否则抛出错误
let fn = () => {}
let newFn = new fn() // fn is not a constructor
4.箭头函数不绑定arguments,取而代之用rest参数解决,同时没有super和new.target(箭头函数没有arguments、super、new.target的绑定,这些值由外围最近一层非箭头函数决定)
let fn = () => {
console.log(arguments)
}
fn() // 报错 arguments is not defined
function fn(){
let f = () => {
console.log(arguments)
}
f();
}
fn(1,2,3)
5.使用call、apply、bind并不会改变箭头函数中的this指向
当对箭头使用call或apply方法时,只会传入参数并调用函数,并不会改变箭头函数中this的指向,当对箭头函数使用bind方法时,只会返回一个预设参数的新函数,并不会改变这个新函数的this指向
window.name = "window_name";
let f1 = function () {
return this.name;
};
let f2 = () => this.name;
let obj = { name: "obj_name" };
console.log(f1.call(obj)); //obj_name
console.log(f2.call(obj)); // window_name
console.log(f1.apply(obj)); // obj_name
console.log(f2.apply(obj)); // window_name
console.log(f1.bind(obj)()); // obj_name
console.log(f2.bind(obj)()); // window_name
6.箭头函数没有原型对象prototype这个属性,由于不可以通过new关键字调用,所以没有构建原型的需求,所以箭头函数没有prototype这个属性
let fn = () => {}
console.log(fn.prototype) // undefined
7.不能使用yield关键字,不能用作Generator函数
七、class类
class作为对象的模板被引入ES6,你可以通过class关键字定义类。class的本质依然是一个函数 类的继承:类的继承通过extends关键字实现
八、promise
这个需要单开一节来讲
九、导入和导出
1.导入 ES6中使用关键字import导入模块(文件) 2.导出 ES6中通过export和export default导出模块 模块化的优点:1.防止命名冲突。2.可复用性强