ES6详解,看了不回来找我

有时候,不是因为你没有能力,也不是因为你缺少勇气,只是因为你付出的努力还太少,所以,成功便不会走向你。而你所需要做的,就是坚定你的梦想,你的目标,你的未来,然后以不达目的誓不罢休的那股劲,去付出你的努力,成功就会慢慢向你靠近。

导读:本篇文章讲解 ES6详解,看了不回来找我,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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})
    
  • 如果一个已经声明的变量用于对象的解构赋值,整个赋值需要在圆括号中进行

可以取到继承得到属性

  • 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;
    //都会报错
    
  • 由于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<args.length;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对象
    1. 数组得展开运算符
    2. 数组得解构赋值

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 
  • 实际开发中的应用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/144817.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!