ES6知识点回顾

398 阅读7分钟

一、let

1、变量声明

let a;
let b,c,d
let f = 521, g = 'iloveyou', h = []

2、注意事项

块儿级作用域 全局,函数,eval

{
    大括号里面就是块儿级作用域
}

比如if else while for

{
    let girl = '张翼飞'
}
console.log('girl')

//输出结果为undefind,若用var的话则会输出’张翼飞‘

不存在变量提升

console.log(song)

let song = '恋爱达人'

不影响作用域链

{
    let a = 'zyf'
    {
        console.log(a)
    }
}
//输出结果为'zyf'

第2点和第4点看起来有点冲突,其实不然,因为,第2点是外面调里面的,第4点是里面调用外面的

3、练习

<body>
    <div class="wrap">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>
        const btn = document.getElementsByClassName('item')
        console.log(btn);
        for(var i = 0;i<btn.length;i++){
            btn[i].onclick=function(){
                btn[i].style.background = 'blue'
        }
      }
    </script>
</body>

结果:

image.png

这是因为

{

​ var i = 0

​ btn[i].onclick=function(){

​ btn[i].style.background = 'blue'

​ }

}

{

​ var i = 1

​ …

}

{

​ var i = 2

​ …

}

{

​ var i = 3

}

先执行循环,循环三次,开辟三个作用域

再次点击时i = 3,三个作用域的i都为3,而btn[3]为undefind,所以此时没反应

而如果将var改为let

{

​ let i = 0

​ btn[i].onclick=function(){

​ btn[i].style.background = 'blue'

​ }

}

{

​ let i = 1

​ …

}

{

​ let i = 2

​ …

}

{

​ let i = 3

​ …

}

他们的作用域是不会互相影响的,所以点击每一个块级元素都会进行背景颜色渲染

二、const

对于数组和对象的元素修改,不算作对常量的修改,不会报错

const Team = ['zyf','ls'];
Team.push('pp')

这个不会报错,因为它的地址没有发生改变

三、对象的简化写法

    // ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
    // 这样的书写更加简洁
    let name = '尚硅谷';
    let change = function(){
        console.log('我爱你');
    }
    const school = {
        name,
        change,
        improve(){
            console.log('你好');
        }
    }
    console.log(school);

输出结果为:

image.png

四、箭头函数

1、this始终指向函数声明所在作用域的this的值,就是比如

const a = ()=>{
    console.log(this.name)
}
window.name = 'shangguigu';
a()

输出的值是'shangguigu',这是因为a是定义在window的作用域里的

2、this是静态的

function getName(){
        console.log(this.name);
    }
    const getName2=()=>{
        console.log(this,name);
    }
    window.name = '尚硅谷';
    const school = {
        name:'张翼飞'
    }
    getName.call(school); // 输出结果为张翼飞
    getName2.call(school);//输出结果为尚硅谷

箭头函数里面this指向的值一旦固定,就无法改变

3、案例

<div id="ad"></div>
    <script>
        let ad = document.getElementById('ad');
        ad.addEventListener("click",function(){
            setTimeout(function(){
                console.log(this);
                this.style.background = 'pink'
            },2000)
        })
 	</script>
// 输出的是window,且点击块级元素没反应

<script>
        let ad = document.getElementById('ad');
        ad.addEventListener("click",()=>{
            setTimeout(()=>{
                console.log(this);
                this.style.background = 'pink'
            },2000)
        })
</script>
// 输出的是div节点,且点击块级元素会改变背景颜色

五、函数参数

1、函数参数的默认值

		//ES6允许给函数参数赋值初始值
        //1、形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
        function add(a, b, c = 10){
            return a + b + c;
        }
        let result = add(1, 2);
        console.log(result); //输出13
        

        function connection({name='zyf',age,sex}){
            console.log(name);  //zyf
            console.log(age);   //20
            console.log(sex);   //男
        }
        connection({age:20,sex:'男'})
    </script>

2、rest参数

function fn(...args){
            console.log(args); //一个长度为5的数组
        }
fn(1,2,2,3,4)

//rest参数必须要写到最后面,rest参数不写到后面会报错

六、Symbol

1、Symbol的声明定义

Symbol相当于唯一表示标识,即使里面的值相同,进行对比,也会返回false

let hd = Symbol('zyf');
let edu = Symbol('zyf');
console.log(hd = edu);
//输出false

打印Symbol里面的值

let cms = Symbol('hdcms');
console.log(cms.description);
//输出结果为:hdcms

Symbol的for用法

let cms = Symbol.for('hdcms');
let zyf = Symbol.for('hdcms');
consloe.log(cms===zyf);
//输出true
console.log(Symbol.keyFor(cms))
//输出结果为:hdcms

这是因为Symbol.for有缓存,所以当zyf的定义和cms一样时,用的是cms的值

2、Symbol的应用场景

let user1 = {
            name:'李四',
        }
        let user2 = {
            name:'李四',
        }
        let grade = {
            [user1.name]:{js: 100, css: 89},
            [user2.name]:{js: 55, css: 55}
        }
        console.log(grade[user1.key]);
//输出结果为:{js: 100, css: 89}
        console.log(grade[user2.key]);
//输出结果为:{js: 55, css: 55}

不用Symbol打印的都是一样的值

let user1 = {
            name:'李四',
            key:Symbol()
        }
        let user2 = {
            name:'李四',
            key:Symbol()
        }
        let grade = {
            [user1.name]:{js: 100, css: 89},
            [user2.name]:{js: 55, css: 55}
        }
        console.log(grade[user1.name]);
//输出结果为:{js: 100, css: 89}
        console.log(grade[user2.name]);
//输出结果为:{js: 55, css: 55}

打印出了理想的结果

Symbol在缓存容器中的使用

class Person{
            static data = {};
            static set(name, value){
                this.data[name] = value
            }
            static get(name){
                return this.data[name]
            }
        }
        let user1 = {
            name: 'zyf',
            operate: '吃饭',
            key: Symbol()
        }
        let user2 = {
            name: 'zyf',
            operate: '洗澡',
            key: Symbol()
        }
        Person.set(user1.key,user1)
        Person.set(user2.key,user2)
        console.log(Person.get(user1.key));
//输出结果为:{ name: 'zyf',operate: '吃饭',key: Symbol()}
        console.log(Person.get(user2.key));
//输出结果为:{ name: 'zyf',operate: '洗澡',key: Symbol()}

3、Symbol对象属性保护

const obj = {
            name: 'zyf',
            [Symbol('name')]:'ls'
        }
for(const key of Reflect.ownKeys(obj)){
            //一般方法无法获取到obj的"[Symbol('name')]",所以可以用Reflect.ownKeys(obj)这种方法
            console.log(key);
        }

七、迭代器

八、生成器

1、生成器函数声明与调用(*符号)

function * gen(){
            console.log(111);
            yield '一只没有耳朵';
            console.log(222);
            yield '一只没有尾巴';
            console.log(333);
            yield '真奇怪';
            console.log(444);
        }
        let iterator = gen();
        iterator.next(); //输出111
        iterator.next(); //输出222
        iterator.next(); //输出333
        iterator.next(); //输出444

image.png

所以此时想要进行四个部分空间内容的打印的话,可以用里面的next()–相当于指针

生成器遍历

function * gen(){
            yield '一只没有耳朵';
            yield '一只没有尾巴';
            yield '真奇怪';
        }
        let iterator = gen();
        for(let v of gen()){
            console.log(v);
        }

九、集合

1、集合介绍与API

let s = new Set();
let s2 = new Set(['zyf','zyf','ls','pp'])
console.log(s2) //{'zyf','ls','pp'},会进行去重的操作

s2.size 		//元素个数
s2.add('lz') 	//添加新的元素
s2.delete('zyf')//删除元素
s2.has('糟心事') //检测
s2.clear()		//清空

2、示例

const arr1 = [1,1,2,2,3,4];
const arr2 = [1,2,6,6,7,8];

//数组去重
console.log([...new Set(arr1)]);  //[1, 2, 3, 4]
//交集
console.log([...new Set(arr1)].filter((item)=> new Set(arr2).has(item))) //[1, 2]
//并集
console.log([...new Set([...arr1,...arr2])]) //[1, 2, 3, 4, 6, 7, 8]
//差集
console.log([...new Set(arr1)].filter((item)=> !new Set(arr2).has(item))) //[3, 4]
//Number.parseInt Number.parseFloat字符串转数组
        console.log(Number.parseInt('5211569你好'));  //5211569
        console.log(Number.parseFloat('3.14569你好11')); //3.14569
​
        //Number.isInteger 判断一个数是否为整数
        console.log(Number.isInteger(5)); //true
        console.log(Number.isInteger(2.5)); //false
​
        //Math.trunc将数字的效数部分抹掉
        console.log(Math.trunc(3.5)); //3
        
        //Math.sign判断一个数列到底为整数 负数 还是零
        console.log(Math.sign(100));  //1
        console.log(Math.sign(0));    //0
        console.log(Math.sign(-20000)); //-1
//对象合并
const obj1 = {
    name:'zyf',
    age:18
}
const obj2 = {
    name:'ls',
    sex:'male'
}
console.log(Object.assign(obj1,obj2))  //{name:'ls', age:18, sex:'male'}

await是拿到resolve和reject里面的值的

const p = new Promise((resolve, reject)=>{
    resolve('111111')
})
//await要与async配合使用,async里面没有await可以,但是使用await时,必须要在async函数里面使用
async function main(){
    try{
        const result = await p; 
        console.log(result);   //当p函数里面为resolve时,这里进行输出
    }catch(e){
        lconsole.log(e)        //当p函数里面为reject时,这里进行输出
    }
}
const fs = require('fs');
       const fn = (urlLoad)=>new Promise((resolve,reject)=>{
            fs.readFile(urlLoad,(err,data)=>{
                   if(err) reject(err);
                   resolve(data)
               })
           })
    async function asy (){
        const fn3 = await fn('./1.md')
        const fn4 = await fn('./2.md')
        console.log(fn3.toString());
        console.log(fn4.toString());
    }
    asy()  //分别输出1.md,2.md的内容

Promise永远的神

let b = 1;
        function fn(){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve((()=>{return '11111'})())
                },2000)
            })
        }
        async function main(){
            b = await fn();
            //输出'11111',会先执行完fn里面的resolve,reject函数,再执行先的console.log(b)语               句
            console.log(b);
        }
        main()
​
​
let b = 1;
        function fn(){
            return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                b = 2
            },2000)
            resolve(6666666)
            })
        };
        async function main(){
            b = await fn();
            console.log(b);  //输出6666666,并且会立马执行,不会等待2秒钟,拿到resolve的值就会立马执行吓一条语句
        }
        main()
​
const school = {
            name:'尚硅谷',
            cities:['北京','上海','深圳'],
            xueke:['前端','java','大数据','运维']
        }
        //对象属性的描述对象
        console.log(Object.keys(school));
        //获取对象所有的值
        console.log(Object.values(school));
        //entries
        console.log(Object.entries(school));

打印结果为

image.png

//将二维数组转为对象
const result1 = [['name','zyf'],['sex','male']];
console.log(Object.fromEntries(result1));  //{name: 'zyf', sex: 'male'}
const m = new Map();
m.set('name','ls');
console.log(Object.fromEntries(m));        //{name: 'ls'}

trimStart和trimEnd分别清楚字符串左边和右边的空白字符串

//数组方法扩展flat,flat后面括号里的值默认为1
const arr1 = [1,2,3,[4,5]];
console.log(arr1.flat());  //[1, 2, 3, 4, 5]
const arr2 = [1,2,[3,4,[5,6]]]
console.log(arr2.flat(2)); //[1, 2, 3, 4, 5, 6]

初版订阅与发布

<script>
        const shopObj = {}
​
        shopObj.list = []
​
        shopObj.listen = function(fn){
            shopObj.list.push(fn)
        }
​
        shopObj.trigger = function(){
            let fn
            for(let i = 0;fn = this.list[i];i++){
                fn(...arguments)
            }
        }
        shopObj.listen(function(color,size){
            console.log(`颜色是${color}`);
            console.log(`尺寸是${size}`);
        })
        shopObj.listen(function(color,size){
            console.log(`再次颜色是${color}`);
            console.log(`再次尺寸是${size}`);
        })
        shopObj.trigger('red',42)
        shopObj.trigger('black',40)
    </script>

foreach是干事用的(执行业务逻辑),map是返回数组拿数据的

十、一些常用的方法

1、数组扁平化

const deps = { 
'采购部':[1,2,3], 
'人事部':[5,8,12], 
'行政部':[5,14,79], 
'运输部':[3,64,105],
}

// 原本写法:
let member = []; 
for (let item in deps){ 
    const value = deps[item];
    if(Array.isArray(value)){ 
    member = [...member,...value] 
} } 
member = [...new Set(member)]

// 现如今写法
let member = Object.values(deps).flat(Infinity);
// 其中使用`Infinity`作为`flat`的参数,使得无需知道被扁平化的数组的维度。

2、关于输入框非空的判断

// 原本写法
if(value !== null && value !== undefined && value !== ''){
    //...
}

//现如今写法
if((value??'') !== ''){ 
    //... 
}

3、列表搜索

列表搜索尽量用find,少用filter