ES6详解,看了不回来找我

简介: ES6简介

ES6简介


ECMAScript 6


ECMAScript 是语言的标准

6是版本号

ES6 = ECMAScript 这门语言的第六代标准

ECMAScript = 语法 + API


ES与Javascript的关系


Javascript(浏览器端)= ECMAScript (语法+API) + DOM + BOM


ES的兼容性


主流浏览器几乎都支持ES6

IE老版本等不支持的浏览器,可以用Babel转码


let和const是什么


声明变量或常量

let代替var

const 声明常量 constant


const


为什么需要const


const就是为了一些初始化后就不希望改变的属性


const的注意事项


使用const声明常量,一旦声明,就必须立即初始化,不能留到以后赋值

const声明常量,允许在不重新赋值的情况下修改它的值


let、const与var的区别


重复声明


已存在的变量,又声明一遍 var允许重复声明,let、const不允许


变量提升


var会提升变量的声明到当前作用域的顶部

let和const不存在变量提升


暂时性死区


只要作用域内存在let、const,它们所声明的变量或常量就自动“绑定”这个区域,不在受到尾部作用域的影响


window对象的属性和方法


在全局作用域中,var声明的变量,通过function声明的函数,会自动变成window对象的属性或方法

let 和 const 不会


块级作用域


什么是块级作用域

var没有块级作用域

let/const有块级作用域


作用域链


内层 -》 外层-》… -》 全局


有哪些块级作用域

{}

for(){}

while(){}

do{}while()

if(){}

switch(){}

函数作用域 function(){}

对象中的{}不构成作用域


模板字符串


表示


模板字符串与一般字符串的区别


一般字符串使用 + 好拼接变量

模板字符串 使用${变量}

输出多行字符串使用\n 也可以直接回车换行

输出 `和\等特殊字符

` hello ${world}`


模板字符串的注入


模板字符串可以注入变量

对象属性

函数

运算

总而言之就是能得到一个值


箭头函数


认识箭头函数


箭头函数的结构


const/let 函数名 = 参数 =》函数体


如何讲一般函数写成箭头函数


箭头函数的注意事项


单个参数


const add = x => {
    return x + 1;
}

无参数或则多个参数()不能省略


单行函数体


const add = (x,y) => x + y;

单行函数体可以同时省略{}和return

多行函数体不能省略


单行对象


const add = (x,y) => {
    return {
        value: x + y;
    };
}
const add = (x,y) => ({
        value: x + y;
})

返回单行函数在{}外面加上 ()浏览器会将他看成对象{}


this指向


全局作用域中的this指向


console.log(this); //window


一般函数(非箭头函数)中的this指向


'use strict';//标注为严格模式
function add(){
    console.log(this);
}
//非严格模式下undefined->window
add(); 
//严格模式下
add(); //undefined
window.add();//window调用


只有在函数调用的时候this指向才确定,不调用的时候,不知道指向谁

this指向和函数在哪里调用没关系,只和谁在调用有关

dom的事件,this就是dom对象

构造函数中的this 就是指向这个对象

apply()和call()中的this指向window

数组中的this指向 数组本身

new 函数返回的对象 第一步创建一个{} 第二部this = {} 第三步值赋给this 最后返回this


箭头函数中的this指向


const calc = {
    add:() => {
        console.log(this);
    }
}
calc.add();//window
/*
  解析:
  结合作用域链
  箭头函数没有this
  所以在calc中找this
  因为对象的{}不构成作用域
  所以最后this指向windwo
*/


箭头函数没有自己的this指向


`use strict`; //开启严格模式
const calc = {
    add:function(){
        const adder = () =>{
            console.log(this);
        };
        adder();
    }
};
calc.add();//指向calc
const addFn = calc.add;
addFn(); //undefined -> window


不适合箭头函数的场景


作为构造函数


const Person = () => {}
new Person();
// 箭头函数没有this指向
// 所以报错


需要使用arguments的时候


function add(){
    console.log(arguments);//arguments [1,2]
}
add(1,2);
//变成箭头函数
const add = () =>  console.log(arguments);
add();//报错 因为 箭头函数中没有arguments
//ES6中会剩余参数可以代替arguments子


例子


const timer = {
    time: 0,
    start: function(){
        btn.addEventListener('click',function(){
            setInterval(function(){
                console.log(this);//这里的setInterval在非严格模式下undefined-》window对象
                this.time++;
                result.innerHTML = this.time;
            },1000);
        },false)
    }
}
//用that 保存上下文的this 解决
const timer = {
    time: 0,
    start: function(){
        let that = this;
        btn.addEventListener('click',function(){
            setInterval(function(){
                this = that;
                console.log(this);//这里的setInterval在非严格模式下undefined-》window对象
                this.time++;
                result.innerHTML = this.time;
            },1000);
        },false)
    }
}
//用箭头函数解决这个问题
const timer = {
    time: 0,
    start: function(){
        btn.addEventListener('click',() =>{
            setInterval(() =>{
                console.log(this);//这里的setInterval在非严格模式下undefined-》window对象
                this.time++;
                result.innerHTML = this.time;
            },1000);
        },false)
    }
}
timer.satrt()
//解析因为箭头函数没有自己的this
//所以在第一个内层的箭头函数中会去上一个函数获取this对象
//但是上一个对象也是箭头函数没有this
//所以在上面找到了timer对象作为this


解构赋值


认识解构赋值


//以前的写法
const arr = [1,2,3];
const a = arr[0];
const b = arr[1];
const c = arr[2];
//解构赋值
const [a,b,c] = [1,2,3]


解构赋值是什么


解析某一数据的结构,将外面想要的东西提取出来,赋值给变量或常量


数组的解构赋值的原理


模式(结构)匹配


[] = [1,2,3] 左右的结构一样都是数组


索引值相同的完成赋值


[a,b,c] = [1,2,3]


const [a,[,,b],c] = [1,[2,4,5],3]
//获取1 5 3


数组结构赋值的默认值


默认值的基本用法


const [a,b] = [];
//const [a,b] = [undefined,undefined]
const [a = 1,b = 2] = []; //设置默认值


默认值生效条件


只有当一个数组成员严格等于(===)undefined时,对应的默认值才会生效

const [a=1,b=2] = [3,0]
//a = 3
//b = 0
const [a=1,b=2] = [3,null]
//a = 3
//b = null
const [a=1,b=2] = [3]
//a = 3
//b = 2


默认值表达式


如果默认值是表达式,默认值表达式是惰性求值的

const func = () => {
   console.log("我被执行了");
    return 2;
}
const [x= func()] = [1];
console.log(x); // 1
//用到了才会去执行这个函数
const [x= func()] = [];
console.log(x); // 2


常见的类数组的解构赋值


arguments


将arguments类数组可以看成数组去解构赋值


function func(){
    const [a,b] = arguments;
    console.log(a,b);
}
func(1,2);


NodeList


const [p1,p2,p3] = document.querySelectorAll('p');

NodeList也可以使用数组的方式解构赋值


函数参数的解构赋值


const array = [1,2];
const add = arr => arr[0]+ arr[1];
//使用解构赋值
const add = ([x,y]) => x + y;
add(array);


交换变量的值


let x = 1;let y = 2;let temp = x;x = y;y = temp;//解构的方式交换[x,y] = [y,x];


对象的解构赋值的原理


模式(结构)匹配


  • {} = {}

属性名相同的完成赋值

  • const {'age':age,'username':username} = {username:'Alex',age:18};

属性名和变量相同可简写

const {age,username} = {username:'Alex',age:18};

可以通过这个取别名

const {'age':age,'username':name} = {username:'Alex',age:18};


对象结构赋值的注意事项


默认值的生效调剂


对象的属性值严格等于undefined的时候,对应的默认值才会生效

数组还是对象的默认值都使用等号 const {username = 'ZhangSan', age = 0} ={username:'alex'}


默认值表达式


如果默认值是表达式,默认值表达式是惰性求值的将一个已声明的变量用于解构赋值


let x = 2;

({x} = {x:1})

1

2

如果一个已经声明的变量用于对象的解构赋值,整个赋值需要在圆括号中进行



const {toString} = {};
console.log(toString);

如果一个已经声明的变量用于对象的解构赋值,整个赋值需要在圆括号中进行


可以取到继承得到属性


const {toString} = {};
console.log(toString);


对象解构赋值的应用

const logPersonInfo = ({username,age}) => {console.log(username,age)}
logPersonInfo({username:'alex',age:18})


const obj {
    x:1,
    y:[2,3,4],
    z:{
        a:5,
        b:6
    }
}
const {y,y:[,yy]} = obj; //只取3 和数组


字符串的解构赋值

数组形式的解构赋值

const [a,b,,c] = 'hello';
console.log(a,b,c)//h e o

对象形式解构赋值

const { 0:a,1:b,length} = 'hello'
console.log(a,b,length)//h e 5

数字和布尔值的解构赋值

const { a = 1 ,toString} = 123;
const { b = 2 ,toString} = true;
//右边转换为了包装类但是没有属性只有值所以取不到

先将等号右边的值转为对象

undefined 和 null的解构赋值

const {toString} = undefined;
const {toString} = null;
//都会报错
• 1
• 2
• 3
  • 由于undefined 和 null 无法转为对象,所以对他们进行解构赋值,都会报错

属性和方法的简洁表示法

对象字面量是什么

实例化构造函数生成对象

const person = new Object();
person.age = 18;
person.speak = function(){};

对象字面量


const person = {
    age:18,
    speak: function(){}
}


属性的简洁表示法

const age = 18;
const person = {
   // age:age
    age
};


键名和变量或常量名一样的时候,可以只写一个


方法的简洁表示
const person = {
   // speak:function(){}
    speak(){}
}


方法可以省略冒号和function关键字


方括号语法

方括号语法的用法

const prop = 'age';
const person = {};
//person.prop = 18;
person[prop] = 18;
const person = {
    [prop]:18
};
//方括号语法可以卸载对象字面量中


方括号中可以放什么

${}


[值或通过计算可以得到的(表达式)]


const prop = 'age';
const func = () => 'age2';
const person = {
    [prop]:18,
    [func()]:18,
    ['sex']:'male',
    ['sex' + '1']:'male'
}

方括号语法和点语法的区别

点语法是方括号语法的特殊形式

点语法使用:属性名有数字、字母、下划线以及$构成,并且数字还不能打头的时候可以使用点语法

当你的属性或方法名是合法标识符时,可以使用点语法,其他情况下请使用方括号语法

函数参数的默认值

认识函数参数的默认值

调用函数的时候传参了,就用传递的参数;如果没传参,就用默认值

函数参数默认值的基本用法

//以前做法
const multiply = (x,y) => {
    if(typeof y === 'undefined') y = 1;
    return x * y;
}
//函数参数默认值
const multiply = (x,y=1) => {
    return x * y;
}

函数参数默认值的注意事项

默认值的生效条件


不传递参数,或者明确的传递的undefined作为参数,只有这两种情况下,默认值才会生效

const multiply = (x,y=1) => {
    return x * y;
}
multiply(2,0); // 2
multiply(2,null); // 0  2*null null被看待成了0
multiply(2,undefined);//2


默认值表达式


如果默认值是表达式,默认值表达式是惰性求值的


设置默认值的小技巧


函数参数的默认值,最好从参数列表的右边开始设置默认值


函数参数默认值的应用

接受很多参数得到时候


const logUser = (username = 'ZhangSan',age = 0,sex = 'male') => console.log(username,age,sex);


接收一个对象作为参数


const logUser = options => console.log(options.username,options.age,optionssex);
const logUser = ({username,age,sex}) => console.log(username,age,sex);
const logUser = ({username= 'ZhangSan',age = 0,sex = 'male'} = {}) => console.log(username,age,sex);


剩余参数

认识剩余参数

const add = (x,y,z,...args) => {}


剩余参数的本质

const add = (x,y,...args) => {
    console.log(x,y,args);
}
add(1,2,3,4,5); // 1 2 [3,4,5]


剩余参数永远都是一个数组,即使没有值,也是空数组


箭头函数的剩余参数

箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号

使用剩余参数代替arguments获取实际参数

const add = function(){
    console.log(arguments);
}
//箭头函数中没有arguments 使用过剩余参数代替
const add = (...args) => {
  console.log(args);
}
add(1,2);

剩余参数的位置

剩余参数只有是最后一个参数,之后不能在有其他参数,否则会报错

剩余参数的应用

const add = (...args) => {
    let sum = 0;
    for(let i=0;i
        sum += args[i];
    }
    return sum;
}


与解构赋值结合使用

const [num,...agrs] = [1,2,3,4]
// num 1
// agrs [2,3,4]
const func  = ([num,..agrs]) => {}
func([1,2,3])
const {x,y,...z} = {
                        a:3,
                        x:1,
                        y:2,
                        b:4
                    }
//x 1 
//y 2
//z {3,4} 剩余元素


展开运算符

认识展开运算符

[3,1,2]
Math.min([3,1,2]) // 错误
Math.min(3,1,2)
[3,1,2] => 3,1,2

数组展开运算符的基本用法

Math.min(...[3,1,2])

区分剩余参数和展开运算符

根本区别

//展开运算符
// [3,1,2] => 3,1,2
//剩余参数
// 3,1,2 => [3,1,2]
  • 他们的操作刚好相反

区分剩余参数和展开运算符


const add = (...agrs) => {
    console.log(args); // [1,2,3]
    console.log(...args); //1 2 3
}
add(1,2,3)
consloe.log([...[1,2,3],4]) // [1,2,3,4]


数组展开运算符的应用

复制数组

const a = [1,2]
const c = [...a]

合并数组

const a = [1,2]
const b = [3]
const c = [4,5]
d = [0,...a,...b,...c] //d [0,1,2,3,4,5]

字符串转为数组

  • 字符串也可按照数组的形式展开
arr = [...'hello']; // arr ["h","e","l","l","o"]

常见的类数组转化为数组

arguments
function func(){
    console.log([...argument])
}


NodeList

let nodeList = [...document.querySelectorAll('p')];

对象展开运算符

展开对象

对象不能直接展开,必须在{}中展开

对象的展开:把属性罗列出来,用逗号分隔,方法一个{}中,构成新的对象

const apple = {
    color:'红色',
    shape:'球形',
    taste:'甜'
};
console.log({...apple})


合并对象

const apple = {
    color:'红色',
    shape:'球形',
    taste:'甜'
};
const pen = {
    color:'黑色',
    shape:'圆柱形',
    use:'写字'
};
console.log({...apple,...pen})
/*
  会拥有所有属性 属性名相同的会被后者覆盖
        {
            color:'黑色',
            shape:'圆柱形',
            taste:'甜',
            use:'写字'
        }
*/

注意事项

空对象的展开

如果展开一个空对象,则没有任何效果

非对象的展开

如果展开的不是对象,则会自动将其转为对象,在将其属性罗列出来

如果展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象

对象中对象属性的展开

对象中还有对象 不会展开对象中的对象属性


对象展开运算符的应用

复制对象


const a = {x:1,y:2};
const b = {a:1};
const c = {...a,...b}


用户参数和默认参数

// 对象解构 函数参数加默认值
const logUser = ({username = 'ZhangSan',age = 0,sex = 'male'} = {}) => {
    console.log(username,age,sex)
}
//使用展开运算符
const logUser = userParam => {
    cons defaultParam = {
        username:'ZhangSan',
        age = 0,
        sex = 'male'
  };
    const param = {...defaultParam,...userParam};
}


Set集合

Set是什么

数组是一系列有序的数据集合

Set是一系列无序、没有重复值的数据集合

const s = new Set();
s.add(1);
s
s.add(1);
// s.length 2
//s {1,2}


Set没有下标取标识每一个值,所以Set是无序的,也不能像数组那样通过下标取访问Set的成员

Set实例的方法和属性

add方法

const s = new Set();
s.add(1).add(2).add(1);

delete方法

s.delete(1);

clear方法

s.clear();//清楚set集合所有内容

forEach方法


s.forEach(function(value,key,set){
    //Set 中的 value = key
    console.log(value,key,set)
    console.log(this) //指向 document
},document)
//按照成员添加进集合的顺序遍历

size属性

s.size

Set构造函数的参数

数组

const s = new Set([1,2,1]);
// s {1,2}

字符串、arguments、NodeLIst、Set等

const s = new Set('hi');
//s {'h','i'}
function func(){
    console.log(new Set(arguments));
}
func(1,2,1)
 console.log(new Set(document.querySelectorAll('p')));
 console.log(new Set(s));


判断重复的方式

const s = new Set([1,2,1]);
//set 对重复值的判断基本遵循严格相等(===)
//但是对于NaN的判断与 === 不同,Set中NaN等于NaN
const s = new Set([NaN,2,1,NaN]);

什么时候使用Set

数组或字符串去重时

不需要通过下标访问,只需要遍历时

为了使用Set提供的方法和属性时(add delete clear has forEach size等)


Set的应用

数组去重

const s = new Set([1,2,1])
console.log([...s])
console.log([...new Set([1,2,1])])

字符串去重

const s = new Set('adsabd');
console.log([...new Set('adsabd')].join('0'))

存放DOM元素

const s = new Set(document.querySelectorAll('p'))
console.log(s)
s.forEach(function(elem){
    elem.style.color = 'red';
});

Map集合

Map是什么

Map和对象都是键值对的集合


键->值 key->value


Map和对象的区别


对象一般用字符串当做键

const obj = { name:'alex',true:'true'}

基本数据类型: 数字、字符串、布尔值、undefined、null


应用类型:引用对象([]、{}、函数、Set、Map等)


都可以作为Map的键


Map实列的属性和方法

set方法

const m = new Map();
m.set('age',18).set(true,'true').set('age',20);
console.log(m)

get方法

const m = new Map();
m.set('age',18).set(true,'true').set('age',20);
console.log(m.get('age'))
//不存在的 会返回undefined

has方法

m.has('age')

delete方法

m.delete('age')
//删除不存在的成员 什么都不会发生 也不会报错

clear方法

m.clear()

forEach方法

m.forEach(function(value,key,map){
    console.log(this);//document
},document)


size属性

//对象没有size属性
m.size


Map构造函数的参数


数组

//只能传二维数组,必须体现出键和值
console.log(new Map(['name','alex'],['age',18]))


Set、Map


//set 中也必须体现出键和值
const s = new Set(['name','alex'],['age',18])
console.log(new Map(s)
const m1 = new Map(['name','alex'],['age',18]);
console.log(new Map(m1))


Map的注意事项


判断键名是否相同的方式


基本遵循严格相等(===)

列外就是NaN ,在Map中是相等的


什么时候使用Map


如果只需要 k - v的结构,或者需要字符串以外的值做键,使用Map更适合

Map的应用

const [p1,p2,p3] = document.querySe;ectoryAll('p')
const n = new Map([p1,'red'],[p2,'green'],[p2,'blue']);
m.forEach(function(color,elem) => {
          elem.style.color = color;
          })

Iterator


作用


遍历器(迭代器)


寻找Iterator


let a = [1,2][Symbol.iterator]() //a Array Iterator {}
a.next() //{value: 1, done: false}
a.next() //{value: 2, done: false}
a.next() //{value: undefined, done: true}


为什么需要iterator


iterator 是统一的一个遍历方式


更方便使用iterator


我们一般不会直接使用iterator 去遍历

比如 es6 提供的 for of


for … of的用法


认识 for…of


const arr = [1,2,3]
/*
  for of 的本质就是封装了这一套东西
    const it = arr[Symbol.iterator]();
    let next = it.next();
    while(!next){
        console.log(next.value);
        next = it.next;
    }
*/
for(const item of arr){
    console.log(item);
}

for of 循环只会遍历出那些done为false时,对应的值


与beak、continue一起使用

const arr = [1,2,3]
for(const item of arr){
    if(item == 2){
        break;
    }
    console.log(item);
}


在for of中取到数组的索引


const arr = [1,2,3]
//keys()得到的就是索引的可遍历对象,可以遍历的索引值
for(const key of arr.keys){
    console.log(key); 
}
//valus()得到的是值
for(const v of arr.values){
    console.log(v); 
}
//entries() 得到是索引 + 值得数组得可遍历对象
for(const entrues of arr.entrues()){
    console.log(entrues); 
}
//使用解构赋值 直接拿到索引 + 值
for(const {index,value} of arr.entrues()){
    console.log(index , value); 
}


原生可遍历与非原生可遍历

什么是可遍历


只要有Symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的

只要可遍历,就可以使用 for…of循环来统一遍历


原生可遍历有哪些


数组

字符串

Set

Map

arguments

NodeList


非原生可遍历有哪些


一般对象 可以使用 for in 自己添加Symbol.iterator方法

const person = {sex:'male',age:18};
    person[Symbol.iterator] = () => {
         let index = 0;
         return {
           next() {
             index++;
           if (index === 1) {
              return {
               value: person.age,
                done: false
              };
             } else if (index === 2) {
             return {
                 value: person.sex,
               done: false
              };
           } else {
             return {
                 done: true
               };
            }
           }
        };
      };


使用了Iterator


原生可遍历

Array数组

String数组

Set

Map

函数得arguments对象

NodeList对象

数组得展开运算符

数组得解构赋值


ES6中新增加方法


includs()方法


判断字符串中是否包含有某些字符

//基本用法
console.log('abc'.includes('a')); // true
console.log('abc'.includes('ab')); // true
console.log('abc'.includes('bc')); // true
console.log('abc'.includes('ac')); // false


// 第二个参数
// 表示开始搜索的位置,默认是0
console.log('abc'.includes('a')); //ture
console.log('abc'.includes('a',0)); //true
console.log('abc'.includes('a',1)); //false


实际开发中的应用



相关文章
|
7月前
|
JavaScript 前端开发 Go
Module加载的详细说明-保证你有所收获
Module加载的详细说明-保证你有所收获
|
7月前
|
前端开发 JavaScript
讲讲ES6中 对象合并
讲讲ES6中 对象合并
85 0
|
JavaScript API
ES6——知识点记录(上)
ES6——知识点记录
98 0
|
缓存 移动开发 JSON
ES6——知识点记录(下)
ES6——知识点记录(上)
59 0
|
缓存 移动开发 前端开发
ES6——知识点记录
ES6——知识点记录
37 0
|
人工智能 自然语言处理 语音技术
pull错代码,恢复到pull之前 ---本地代码回退
pull错代码,恢复到pull之前 ---本地代码回退
164 0
|
前端开发
|
JSON 前端开发 JavaScript
前端实战【ES6】你会ES6,但是你真的会用吗?
前端实战【ES6】你会ES6,但是你真的会用吗?
143 0
前端实战【ES6】你会ES6,但是你真的会用吗?
|
JavaScript 前端开发
每天3分钟,重学ES6-ES12(十六)错误异常处理方案
每天3分钟,重学ES6-ES12(十六)错误异常处理方案
118 0
|
监控 前端开发 JavaScript
每天3分钟,重学ES6-ES12(十五)异步代码处理方案
每天3分钟,重学ES6-ES12(十五)异步代码处理方案
103 0