ES6知识点汇总

一、let关键字

let关键字用来声明变量,使用let声明的变量有几个特点:

  • 不允许重复声明
  • 有块级作用域
  • 不存在变量提升
  • 不影响作用域链

let关键字代码说明

//let不允许重复声明 
let a=2;
let a=3;
console.log(a);
//报错:uncaught SyntaxError:Identefter 'a'has already been declared

//let不允许重复声明
function func(a){
  let a=9;
}
func();//报错:uncaught SyntaxError:Identefter 'a'has already been declared

//var会提升变量的声明到当前作用域的顶部
console.log(a);//undefined
var a=10;

//let const不存在变量的提升
console.log(b); // Cannot access'b' before initialization
let b = 10;

//暂时性死区:只要作用城内存在let const
//他们所声明的变量或者常量就自动绑定这个区域,不再受到外部作用域的影响
let a = 2;
function func() {
 console.log(a); //Cannot access 'a' before initialization
 let a = 1;
}
func();

//暂时性死区:只要作用城内存在let const
//他们所声明的变量或者常量就自动绑定这个区域,不再受到外部作用域的影响
let b = 1;
function fun() {
 console.log(a); //Cannot access 'a' before initialization
}
fun();

//window对象的属性和方法
//全局作用域中,var声明的变量,通过function声明的函数,会自动变成window对象的属性和方法
//let const 不会
//var function
var age= 19;
function add() {}
console. log(window.age);// 19
console.log(window.add === add); //true


//块级作用域:var没有块级作用域
for (vari=0;i<3;i++) { 
//console. log(i);//012
}
console.log(i);//3

 //let const有块级作用域
for(leti=0;i<3;i++) {
//console.Log(i);//012
}
console.log(i);// Uncaught ReferenceError: i is not defined

二、const关键字

const关键字用来声明常量,const声明有以下特点:

  • 声明必须赋初始值 
  • 标识符一般为大写(习惯)
  • 不允许重复声明
  • 值不允许修改
  • 有块级作用域

const关键字代码说明

 //const声明常量
const dog = '旺财' ;
console.log(dog); //旺财

 //不允许重复声明
const a = 1;
const a = 3;
console.log(a);//SyntaxError: Identifier 'a' has already been declared

//不允许重复声明注意:对数组元素的修改和对对象内部的修改是可以的(数组和对象存的是引用地址
//基本数据类型
const sex='male';
sex = 'female';
console.log(sex);//Assignment to constant variable.
//引用数据类型
const person ={
 username: 'Cai'
}
person.username ='Zhangsan',
console.log(person);

三、模板字符串

模板宇符串(template string)是增强版的宇符串,用反引号(`)标识
模板宇符串特点:

•字符串中可以出现换行符;
•可以使用 $(xxx}形式引用变量
•对于模板字符串 所有的空格 换行 缩进都会被保留在输出之中 怎么写就怎么输出

//一般字符串:"Cai"  'Lily'
//模板字符串:`Cai`
const username1 = "Cai";
const username2 = `Cai`;
console.log(username1, username2); //Cai Cai
console.log(username1 === username2) //true

//模板字符串与一般字符串的区别
//和其他东西一起注入的时候,使用模板字符串方便注入
const person = {
 name:'Cai',
 age: 19,
 sex:'Female'
}
//一般字符串的做法
const info = '我叫' + person.name',我今年' + person.age +'岁了,' +'我的性别是'+person.sex;
console.log(info);//我叫Cai,我今年19岁了,我的性别是Female

//模板字符串与一般字符串的区别
//和其他东西一起注入的时候,使用模板字符串方便注入
const person = {
name:'Cai',
age: 19
sex: 'Female'
//模板字符串的做法
const info =`我叫${person.name},年龄${person.age},性别${person.sex},`;
console.log(info);//我叫Cai,年龄19,性别Female

 //输出多行字符
//一般的字符串
const info ='第一行\n第二行';
console.log(info);
//对于模板字符串所有的空格 换行缩进都会被保留在输出之中怎么写就怎么输出
const info1 =`第一行
第二行`;
console.log(info1); 

        //输出`和\等特殊字符
        //   const info = `\``;
        // console.log(info); //`
        //  const info = `\\`;
        //  console.log(info); //\

 只要最后可以得出一个值的会可以通过${}注入到模板字符串中;看下面代码解说

         const username = 'Cai';
         const person = {
            age: 19,
            sex: 'Female'
        }

         const getSex = function(sex) {
            return sex === 'Female' ? 'Female' : 'Male'
        }

        //只要最终可以得出一个值的就可以通过${}注入到模板字符串中

        const result = `${username},${person.age-1},${getSex(person.sex)}`;
        console.log(result); //Cai,18,Female

 四、模板字符串练习案例

  <script>
        const students = [{
            username: 'Cai',
            age: 18,
            sex: 'male'
        }, {
            username: 'zhangsan',
            age: 30,
            sex: 'male'
        }, {
            username: 'lisi',
            age: 13,
            sex: 'male'
        }]

        const list = document.getElementById("list");
        let html = '';
        for (let i = 0; i < students.length; i++) {
            html += `<li>我的名字是${students[i].username},我的年龄是${students[i].age},我的性别是${students[i].sex}</li>`;
        }
        list.innerHTML = html;
        
      </script>

五、箭头函数

ES6允许使用箭头(=>) 定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义
箭头函数的注意点

  • 如果形参只有一个,则小括号可以省略
  • 函数体如果只有一条语句,则花括号可以省略,并省略return,西数的返回值为该条语句的执行结果
  • 箭头函数 this 指向声明时所在作用域下 this 的值
  • 箭头函数不能作为构造函数实例化
  • 不能使用 arguments
 //箭头函数
//箭头函数的结构: const/Let 函数名=参数=>函数体
const add = (x, y) => {
return X + y;
}; 
console.log(add(1,2));//3
//将一般函数改写成箭头函数
function add() {}; //声明形式
const add = function() {}; //函数表达式形式
const add = () => {}; //箭头函数的形式
 <script>
        //箭头函数
        //箭头函数的结构:const/let 函数名= 参数=>函数体
        const add = (x, y) => {
            return x + y;
        };
        console.log(add(1, 2)); //3

        //将一般函数改写成箭头函数
        function add() {}; //声明形式
        const add = function() {}; //函数表达式形式
        const add = () => {}; //箭头函数的形式
    </script>

箭头函数的注意事项

1、单个参数可以省略圆括号


        //单个参数可以省略圆括号
        const add = x => {
            return x + 1
        };
        console.log(add(1)); //2

2、无参数或多个参数不可以省略圆括号

   //无参数或多个参数不可以省略圆括号
        const add = () => {
            return 1 + 1
        }
        console.log(add()); //2

3、当行函数体可以省略{}和return

       //单行函数体:可以同时省略{}和return
        const add = (x, y) => x + y;
        console.log(add(1, 2)); //3
 //如果箭头函数返回单行对象 可以在{}外面加上()让浏览器不再认为那是函数体的花括号
        const add = (x, y) => ({
            value: x + y
        })
        console.log(add(1, 1));

六、非箭头函数中的this指向问题

  • 全局作用域中的this指向window
  • 函数中的this,只有函数被调用时,才有明确的指向
  • this指向调用其所在函数的那个对象
  • 没有具体调用对象,this指向undefined,在非严格模式下指向window
 <script>
        //全局作用域中的this指向
        // console.log(this); //window

        //一般函数(非箭头函数)中的this指向问题
        //  'use strict';

        function add() {
            console.log(this);

            //严格模式下this指向undefined
            //undefined ->window(非严格模式下转化为window)
        }

        add();


        //构造函数中的this指向
        function Person(username, password) {
            this.username = username;
            this.password = password;
            console.log(this); //构造函数中的this指向构造函数实例化后生成的对象
        }

        var p = new Person('Cai', 12);
    </script>

七、箭头中的this指向问题

  • 箭头函数没有自己的this
  • 箭头函数中的this是通过作用域链查找的
      //箭头函数中的this指向问题
        //箭头函数没有自己的this
        const calc = {
            add: () => {
                console.log(this);
            }
        }
        calc.add(); //window

        //练习
        const calc = {
            add: function() {
                const adder = () => {
                    console.log(this); 
                }
                adder();
            }
        }

        calc.add();//calc

  //练习
        const calc = {
            add: function() {
                const adder = () => {
                    console.log(this);
                }
                adder();
            }
        }

        const addFn = calc.add;
        addFn(); //undefined->window

不适合箭头函数的场景

  • 作为构造函数
  • 需要this指向调用对象的时候
  • 需要使用arguments的时候

八、解构赋值

解构赋值:解析某一数据的结构,将我们想要的东西提取出来赋值给变量

数组解构赋值的原理

数组解构赋值的原理:模式(解构)匹配,索引值相同的完成赋值

       //模式匹配 索引值完成赋值
        const [a, b, c] = [1, 2, 3];
        console.log(a, b, c);
      //不取的直接用逗号跳过
        const [a, [b, , ], e] = [1, [2, 4, 5], 3];
        console.log(a, b, e); //1 2 3

数组解构赋值的默认值

默认值的基本用法

 <script>
        // 默认值的基本用法

        // const [a, b] = [];
        // const [a, b] = [undefined, undefined];

        //  const [a = 1, b = 2] = [];
        //  console.log(a, b); //1 2

        //默认值的生效条件
        //只有当一个数组成员严格等于undefined时对应的默认值才会生效

        //  const [a = 1, b = 2] = [3, 0];
        //  console.log(a, b); //3 0


        // const [a = 1, b = 2] = [3, null];
        // console.log(a, b); // 3 null

        //  const [a = 1, b = 2] = [3];
        //  console.log(a, b); //3 2

        //默认值表达式  默认值表达式是惰性求值的
        // const func = () => {
        //     console.log('我被执行了');
        //     return 2;
        // }

        // const [x = func()] = [1];
        // console.log(x); //1


        const func = () => {
            console.log('我被执行了');
            return 2;
        }

        const [x = func()] = [];
        console.log(x); // 我被执行了  2
    </script>

常见的类数组解构赋值

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

        const [p1, p2, p3] = document.querySelectorAll('p');
        console.log(p1, p2, p3);
 //函数参数的结构赋值
        const array = [1, 2];
        const add = ([x, y]) => x + y;
        console.log(add(array)); //3
      //交换变量的值
        let x = 1;
        let y = 2;
        [x, y] = [y, x];
        console.log(x, y); //2 1

对象的解构赋值

  //模式匹配,属性名相同的完成赋值
        const {
            age,
            username,
            password
        } = {
            age: 18,
            username: 'Cai',
            password: 123
        }
        console.log(age, username, password); //18 'Cai' 123
  //取别名
        const {
            age: age,
            username: uname
        } = {
            age: 19,
            username: 'Li'
        }
        console.log(age, uname); //19 'Li'
   //对象的属性值严格等于undefined时对应的值才会生效

        const {
            username = 'Zhang', age = 0
        } = {
            username: 'alex'
        }

        console.log(username, age); //alex  0
        //如果将一个已经声明的变量用于对象的解构赋值
        //整个赋值需要在圆括号中进行
        let x = 2;
        ({
            x
        } = {
            x: 1
        })
        console.log(x); //1
//函数参数的解构赋值
        const Person = ({
            age,
            username
        }) => console.log(username, age); //
        Person({
            age: 19,
            username: 'Cai'
        })
       //复杂的嵌套
        const obj = {
            x: 1,
            y: [1, 2, 3],
            z: {
                a: 5,
                b: 6
            }
        };
        const {
            y,
            y: [, , ss],
            z
        } = obj;
        console.log(ss, y, z); 

字符串的解构赋值

       //字符串的解构赋值
        //按照数组的形式
        const [a, b, , , e] = 'hello';
        console.log(a, b, e); // h e o
        //字符串的解构赋值
        //按照对象的形式
        const {
            0: a,
            1: b
        } = 'hello'

        console.log(a, b); // h e

九、对象字面量的增强与函数参数的默认值

        //对象字面量
        //实例化构造函数生成对象
        const person = new Object();
        person.age = 18;
        person.speak = function() {};
        //对象字面量
        const person = {
            age: 18,
            speak: function() {}
        }

属性的简洁表示法:键名和变量名或者常量名一样的时候,可以只写一个

   //属性的简洁表示法:键名和变量或者常量名一样的时候,可以只写一个
        const age = 19;
        const person = {
            // 'age': age
            age
        };
        console.log(person);

方法的简洁表示法:可以省略冒号和function关键字

 //方法的简洁表示法
        //方法可以省略冒号和function关键字
        const person = {
            // speak: function() {}
            speak() {

            }
        }
        console.log(person);

方括号语法

  //方括号语法和点语法
        const prop = 'age';
        const person = {
            [prop]: 19
        };
        console.log(person);

函数参数的默认值

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

  const multiple = (x, y) => {
            if (typeof y === 'undefined') {
                y = 1;
            }
            return x * y;
        }
        console.log(multiple(2, 2)); //4

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

        //默认值的生效条件
        // 不传递参数或者明确的传递undefined参数 只有这两种情况下 默认值才会生效
        const multiply = (x, y = 1) => x * y
        console.log(multiply(2, 0)); //0
        console.log(multiply(2, null)); //0
        console.log(multiply(2, undefined)); //2

        //函数参数的默认值 最好从列表的右边开始
        // const multiply = (x = 1, y) => x * y;
        // console.log(multiply(undefined, 2)); //2
 
        const multiply = (x, y = 1) => x * y;
        console.log(multiply(2)); //2

十、剩余参数

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

        // 认识剩余参数
        //剩余参数永远是个数组 即使没有值 也是空数组
        const add = (x, y, z, ...args) => {
            console.log(x, y, z, args);
        }

        add(1, 2, 3, 4, 5)

剩余参数的注意事项

        //箭头函数的剩余参数
        //  箭头函数的参数部分即使只有一个剩余参数也不能省略圆括号
        const add = (...args) => {

        }

//使用剩余参数替代arguments获取实际参数
        // const add = function() {
        //     console.log(argments);
        // }

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

         //剩余参数的位置
        //剩余参数只能是最后一个参数 之后不能再有其他参数 否则会报错
        const add = (x, y, ...args) => {
            console.log(x, y, args);
        }

        add(1, 2, 3, 4, 5, 6)

 剩余参数的应用

      //  剩余参数与解构赋值结合使用
        // const [a, ...args] = [1, 2, 3, 4, 5];
        // console.log(a, args);

        const func = ([num, ...args]) => {}
        func([1, 2, 3, 4])

   const {
            x,
            y,
            ...z
        } = {
            x: 1,
            b: 2,
            y: 3,
            d: 4
        }
        console.log(x, y, z);

十一、展开运算符

       //数组展开运算符的基本用法
        console.log(Math.min(...[2, 33, 44])); //2
        //相当于
        console.log(Math.min(3, 33, 22)); //3

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

      //区分剩余参数和展开运算符
        //剩余参数   2,3,4->:[2,3,4]
        //展开运算符:  [2,3,4]->2,3,4

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

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

数组展开运算符的应用

 <script>
        // 复制数组
        const arr1 = [3, 4, 5, 6];
        const arr2 = [...arr1]
        console.log(arr2); // [3, 4, 5, 6]

        //合并数组
        const arr3 = [1, 2, 3];
        const arr4 = [4, 5, 6]
        console.log([99, 98, ...arr3, ...arr4, 100]); //[99, 98, 1, 2, 3, 4, 5, 6, 100]

        //字符串转为数组
        console.log(...
                'Cai') //C a i
        console.log([...
                'Cai'
            ]) //['C', 'a', 'i']
    </script>

对象的展开

    //对象的展开
        const apple = {
            color: 'red',
            taste: 'nice'
        }

        console.log({...apple
        });

        console.log({...apple
        } === apple); //false


        //合并对象
        // 新对象拥有全部的属性 相同的属性 后者覆盖前者
        const apple = {
            color: '红色',
            shape: '球形',
            taste: '甜'
        }

        const pen = {
            color: '黑色',
            shape: '长方形',
            use: '写字'
        }

        console.log({...apple,
            ...pen
        });
   // 对象中属性的展开
        // 不对展开对象中的对象属性
        const app = {
            features: {
                taste: '甜'
            }
        }

        const pen = {
            features: {
                color: '黑色',
                shape: '圆柱形'
            },
            use: '写字'
        }

        console.log({...app,
            ...pen
        })

十二、Set和Map数据结构

        //Set
        //数组:数组是一系列有序的数据集合
        //Set:是一系列无序,没有重复值的数据集合
        const s = new Set();
        s.add(1);
        s.add(2);
        //set中不能允许有重复的值
        console.log(s);
        //set没有下标去标识每一个值,所以set是无序的也不能像数组那样通过下标去访问set的成员

set实例的属性和方法

      // set实例的属性和方法
        //add方法添加成员
        const s = new Set();
        s.add(1).add(2).add(3);
        console.log(s);

        //has方法 判断是否有成员
        console.log(s.has(1)); //true
        console.log(s.has(100)); //false

        //delete删除
        s.delete(1);
        //使用delete删除不存在的成员,什么都不会发生,也不会报错
        s.delete(9);
        console.log(s)

        //clear方法 一键清除
        //  s.clear();
        //  console.log(s)

        //forEach

        s.forEach(function(value, key, set) {
            //Set中value=key
            console.log(value, key, set === s)

        })
        console.log(s)

        //size属性

        console.log(s.size) //2

set构造函数的参数

  • 数组
  • 字符串、arguments、NodeList、Set等
<body>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <script>
        //数组
        const s = new Set([1, 2, 3, 4, 5])
        console.log(s);

        //字符串
        console.log(new Set('hello'));
        //arguments
        function func() {
            console.log(new Set(arguments));
        }

        func(1, 2, 3)

        //nodeList
        console.log(new Set(document.querySelectorAll('p')));
    </script>
</body>

Set的注意事项 

  <script>
        //判断重复的方式
        const s = new Set([1, 2, 3, 1]);
        console.log(s); //{ 1,2,3}

        //Set对重复的判断结伴遵循严格相等的原则(===)
        //但是对于NaN的判断与===不同,Set中的NaN等于NaN
        console.log(1 === 1); //true
        console.log(NaN === NaN); //false

        const s1 = new Set([NaN, 1, 3, NaN]);
        console.log(s1); // {NaN, 1, 3}
    </script>

什么时候用Set?

  • 数组或字符串去重时
  • 不需要通过下标访问的时候,只需要遍历时
  • 为了使用Set提供的方法和属性的时候(add、delete、clear、has、forEach、size等)

Set的应用

//数组去重
console.log([...new Set([1,2,3,1])]);//[1,2,3]
//字符串去重
console.log([...new Set('aabcd')]).join(' ');//bcd

十三、Map

  <script>
        //Map和对象都是键值对的集合
        //对象
        const person = {
            name: 'Cai',
            age: 18
        }

        //Map
        const m = new Map();
        console.log(m);
        m.set('age', 19);
        m.set('name', 'Zhan')
        console.log(m);

        // Map和对象的区别
        //对象一般用字符串当做键


        // 基本数据类型:数字、字符、undefined、布尔值、null
        //引用数据类型:对象([],{},函数,Set,Map()等)
        //以上的都可以作为map的键
        const l = new Map();
        m.set('name', 'Zhangx');
        m.set('age', 20);
        m.set(true, 'true');
        m.set(undefined, 'undefined');
    </script>


 

<script>
 const m=new Map();
 //使用set添加新成员,键如果已经存在,后面添加的键值对覆盖已有的
 m.set('age',18).set(true,'true').set('age',22);
console.log(m);
</script>

 

 <script>
        //set方法
        const m = new Map();
        //使用set添加新成员,键如果已经存在,后面添加的键值对覆盖已有的
        m.set('age', 18).set(true, 'true').set('age', 22)
        console.log(m);

        //get
        console.log(m);
        console.log(m.get('age')); //22
        console.log(m.get(true)); //true
        //get获取到不存在的成员 返回undefined
        console.log(m.get('name')); //undefined

        //has
        console.log(m.has('age')) //true
            //使用delete删除不存在的成员什么都不发生也不报错
        m.delete('name');

        //clear一键删除
        // m.clear();
        // console.log(m)

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

        // 属性size
        console.log(m.size) //2
    </script>

 

Map构造函数的参数

 <script>
//只能传二维数组 而且必须体现出键值
console.log(new Map([
 ['name', 'Cai'],
 ['age', 18],
]));
//SetMap
const s = new Set([
 ['name', 'Li'], 
 ['age',100]
]); 
console.log(new Map(s));
console.log(s);
//Map 复制一个新的Map
const s2 = newMap([
 ['name', 'LL'], 
 ['sex', 'male ']
]);
console.log(s2);
const s3 = new Map(s2);
console.log(s3); 
console.log(s2 === s3); //false
</script>

 

Map中的注意事项

      //Map中NaN等于NaN
        const s4 = new Map();
        s4.set(NaN, 1).set(NaN, 2);
        console.log(s4);

        //什么时候使用Map
        //如果只是需要key-value的结构,或者需要字符串以外的值做键
        //  只有模拟现实世界的实体时,才使用对象
        const person = {};

 

Set和Map总结 

 Set/Map实例的方法与属性
Set                            Map
add()                        set()/get()
has()                        has()
delete() /clear()        delete() /clear()
forEach()                 forEach()
size属性                  size属性
Set/Map构造函数的参数

  • Set:数组、字符串、arguments、NodeList、 Set等 
  • Map:数组(二维数组)、Set、Map等
  • 基本可用严格相等(===)判断
  • 例外:对于 NaN 的判断与===不同, Set/Map中NaN等 于NaN

 十四、遍历器for...of

        //Iterator的作用
        //遍历器(迭代器)用来遍历的
        //使用
        const it = [1, 2][Symbol.iterator]();
        console.log(it.next()); //{value: 1, done: false}
        console.log(it.next()); //{value: 1, done: false}
        console.log(it.next()); //{value: undefined, done: true}
        //it可遍历对象(可迭代器)
        //Symbol.iterator:可遍历对象的生成方法
        //什么是iterator?
        //Symbol.iterator(可遍历对象生成的方法)->it(可遍历对象)->it.next()->...(直到done为true)
   const it = [1, 2, 3][Symbol.iterator]();
        console.log(it.next());
        console.log(it.next());
        console.log(it.next());
        console.log(it.next());

for...of

     const it = [1, 2, 3];
         for (const item of it) {
            console.log(item); // 1  2  3
        }
 // const it = [1, 2, 3];
// for (const item of it){
// console.Log(item);//1 2
//
const it = [1, 2, 3, 45];
for (const item of it)
{
   console.log(item);
}
//在for of 中取得数组的索引值
const arr1=[1, 2, 3] 
//keys()得到的是索引的可遍历对象 可以遍历出索引值 
for (const key of arr1.keys()){ 
 console.log(key);//0 1 2
}
//values()得到的是指的可遍历对象 可以遍历出值  
for (const value of arr1.values ())
{
  console.log(value);//1 2 3
}
//entries() 得到的是索引+值组成的数组的可遍历对象 
for (const entries of arr1.entries())
{
 console.log(entries);//[8, 1] [1, 2][2,3]
}
//或者
for (const [index, value] of arr1.entries())
{
  console.log(index, value);//0 1 1 2 2 3
}

什么是原生可遍历?

  • 只要有Symbol.iterator方法并且这个方法可以生成可遍历对象就是可遍历的
  • 只要可遍历就可以使用for of循环来统一遍历

原生可遍历有哪些?

  • 数组、字符串、Set、Map、arguments、NodeList

非原生可遍历有哪些?

  • 一般的对象

十五、ES6新增的方法

字符串中新增的方法

includes()判断字符串中是否包含某些字符

  <script>
        //includes()判断字符串中是否包含某些字符
        console.log('abc'.includes('a')); //true
        console.log('abcd'.includes('abc')); //true
        console.log('abcs'.includes('f')); //false

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


        //在实际开发中的应用
        //https://www.imooc.com/course/list
        //https://www.imooc.com/course/list?c=fe&sort=pop&name=value
        let url = 'https:www.imooc.com/course/list';
        const addURLParam = (url, name, value) => {
            url += url.includes('?') ? '&' : '?';
            url += `${name}=${value}`
            return url;
        }
        url = addURLParam(url, 'c', 'fe')
        url = addURLParam(url, 'sort', 'pop')

        console.log(url);
    </script>

padStart()和padEnd

padStart()用于头部补全,padEnd()用于尾部补全。

参数(接收两个参数):

第一个参数,当字符串需要填充到的目标长度。如果这个值小于当前字符串的长度,则返回当前字符串本身。

第二个参数,用于补充的字符串,如果字符串长度过长,则会删除后面的多出的字符串,进行补全。

 //补全字符串的长度
console.log('a'.padStart(5, 'ba')); //babaa 
console.log('x'.padEnd(4,'d')); //xddd
//注意事项:当元字符串的长度, 等于或大于最大长度, 不会消减原来的字符串
//字符串补全不生效返回原来的字符串
console.log('xxx' .padStart(2,'ab'))//xxx
console.log('xxx'.padEnd(2, 'ab'))//xxx
//用来补全的字符串与原字符串长度之 和超过了最大的长度 
//截出超出位数的补全字符串, 原字符串不动 
console.log('xxx' .padStart(10, '0123456789')); //0123456xxx 
console.log('xxx'.padEnd(10, '0123456789'));  //xxx0123456
//如果省略第二个参数, 默认使用空格来填充 
console.log('x'.padStart(4));// x
console.log('x'.padEnd(4));//x
//在实际开发中的应用
//显示日期格式
//2020-10-10
//2020-1-2
console.log('10' .padStart(2, 0));
console.log('1' .padStart(2, 0));

适用场景:

      //在实际开发中的应用
        //显示日期格式
        //2020-10-10
        //2020-1-2
        console.log('10'.padStart(2, 0));//10
        console.log('1'.padStart(2, 0));//01

trimStart()、trimEnd()、trimLeft()、trimRight()、trim()

 <script>
//清除字符串的首或尾空格 中间的不会清除 
const S = a C
console.log(s.trimStart());//头部
console.log(s.trimEnd ());//尾部
console.log(s.trimLeft ());//左边
console.log(s.trimRight(); //右边 
console.log(s.trim ());//左右(头尾) 两边部分
</script> 

 数组中新增的方法

 <script>
//includes() 判断数组中是否包含某个成员
console.log([1, 2, 3].includes('2')); //false
console.1og([1, 2, 3].includes(2)); //true //第二个参数表示搜索的起始位置默认值是0 
console.1og([1, 2, 3].includes(2, 1));//true  console.1og([1, 2, 3].includes(2, 3));//faLse 
//基本遵循严格相等(===) 但是对于NaN的判断与===不同
//includes认为NaN===NaN
console.log(NaN === NaN); //faLse
console.log([1, 2, NaN].includes( NaN));  //true
//在实际中的应用
//数组去重[1,2,3,1]
const arr =[];
for (const item of[1, 2, 3, 2, 1]){
 if(!arr.includes(item)){ arr.push(item);
 }
}
console.log(arr)//[1,2,3]
</script>

find()和findIndex()函数详解

find()函数用来查找目标元素(查找符合条件的第一个元素),它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined。回调函数有三个参数。value:当前的数组元素。index:当前索引值。arr:数组本身

       //find(): 找到满足条件的一个立即返回
        console.log([10, 20, 30, 50, 100].find((value, index, arr) => {

            return value > 10; //20
        }))
   

findIndex()函数返回符合条件的值的位置(索引),找不到就返回-1。

     //findIndex():找到满足条件的一个,立即返回索引
        console.log([10, 20, 30, 50, 100].findIndex((value, index, arr) => {
            return value > 10; //1
        }))
 <script>
/find():找到满足条件的一个立即返回
//findIndex(): 找到满足条件的一个,立即返回索引
[10, 20, 30, 50, 100].find((value, index, arr) =>{
console.log(value, index, arr)
})
//find():找到满足条件的一个立即返回
console.log([10, 20, 30, 50, 100].find((value,index,arr) =>{
return value > 10; //20
}))
//findIndex():找到满足条件的一个, 立即返回索引
console.log([18, 20, 30, 50, 100].findIndex((value, index, arr) => { 
return value >10;//1
})) 
</script>

应用场景

 //应用场景
const student : =[{
name: 'Cai'
sex: 女,
age: 19
},{
name: 'Lily'
age: 20,
sex:
},{
name: 'LL'
age: 22,
sex: '男'
}];
console.log(student.find(value =>
value.sex === '女'
))
console.log(student.findIndex(vaLue => 
value.sex === 女'
))

对象的新增方法和属性

Object.assign(目标对象,源对象1,源对象2,……)用来合并对象,返回的是目标对象

  • 同名属性的替换:后面的属性会替换掉前面的属性

  • 基本数据类型作为源对象 ,与对象的展开相似 先转换成对象再合并

 <script>
//Object.assign()用来合并对象
const apple = {
color: '红色',
shape: '圆形',
taste:'甜'
}
const pen = {
color: '黑色',
shape: 圆柱形·
use: '写字'
}
//0bject.assign() 直接合并到了第一个参数中, 返回的就是合并之后的对象
console. log(Object.assign(apple, pen)); 
console.log(apple === 0bject.assign(apple,pen)); //true
//可以合并多个对象
console.1og(Object.assign({}, apple, pen))
 //返回结果: 新的对象
</script>

        const apple1 = {
            color: ['红色', '蓝色'],
            shape: '圆形',
            taste: '甜'
        }
        const pen1 = {
            color: ['黑色', '金色'],
            shape: '圆柱形',
            use: '写字'
        }

        console.log(Object.assign({}, apple1, pen1))

应用场景:合并默认参数和默认参数

 //合并默认参数和默认参数
        const logUser = userOptions => {
                const Default = {
                    username: 'Zhangsan',
                    age: 0,
                    sex: 'male'
                }
                const options = Object.assign({},
                    Default, userOptions);
                console.log(options);
            }
            //logUser();

        logUser({
            username: 'Cai'
        })

 在这里插入图片描述

Object.keys()、Object.values()、Object.entries()

  • Object.keys():获取对象中的键

  • Object.values():获取对象中的值

  • Object.entries():获取对象的键值

 const person =
name: 'Cai',
age: 9,
hobby: 'play'
}
console.log(Object.keys(person)) 
console.log(Object.values(person));
console.log(Object.entries person));

 

对象的Object.keys()、Object.values()、Object.entries()与数组的keys()、values()、entries()的方法的区别

  • 数组的keys()、values()、entries()的方法是实例方法,返回的都是Iterator

  • 对象的Object.keys()、Object.values()、Object.entries()等方法是构造方法 返回的是数组

 <script>
        const person = {
            name: 'Cai',
            age: 9,
            hobby: 'play'
        }

        console.log(Object.keys(person))
        console.log(Object.values(person));
        console.log(Object.entries(person));


        //与数组类似方法的区别
        //数组的keys()、values()、entries()的方法是实例方法,返回的都是Iterator
        //对象的Object.keys()、Object.values()、Object.entries()等方法是构造方法 返回的是数组
        console.log([1, 2, 3].keys());
        console.log([1, 2, 3].values());
        console.log([1, 2, 3].entries());
    </script>

十六、Promise

Promise的基本用法

     const p = new Promise((resolve, reject) => {
            //Promise有三种状态,一是开始pending(未完成)
            //执行 resolve变成fulfilled( resolved)已成功
            //执行reject变成reject 已失败
            //Promise的状态一旦变化了 就不会再改变了
            //pending=>fulfilled( resolved)已成功
            resolve({
                username: 'li'
            });

            //pending=>rejected已失败
            //  reject();

        })

        //then方法
        p.then((data) => {
            console.log('success', data);
        }, () => {
            console.log('error');
        })

        console.log(p);

then()方法

 <script>
        const p = new Promise((resolve, reject) => {
            //resolve();
            reject();

        });

        p.then(
            () => {
                console.log('success');
            },
            () => {
                console.log('err');
                return 123;
                //在then的回调函数中,return后面的东西,会用Promise包装一下
                //return undefined
                //等价于
                //return  new Promise((resolve, reject) => {
                //resolve(undefined);
                //})
                //默认返回的永远都是成功状态的Promise对象
                //return new Promise((resolve, reject) => {
                //    reject('reason')
                //});

            }).then(
            (data) => {
                console.log('success2', data);
                //  return undefined;等价于
                return new Promise((resolve, reject) => {
                    resolve(undefined);
                })
            },
            () => {
                console.log('err2');
            }
        ).then(
            (data) => {
                console.log('success3', data);
            }, (err) => {
                console.log('err3', err);
            })



        //then什么时候执行
        //pending->fulfilled时,执行then的第一个回调函数
        //pending->resolved时,执行then的第二个回调函数

        //执行后的返回的值: 返回一个新的Promise对象
    </script>

catch()方法

  • catch专门用来处理失败状态

  • catch()可以捕获它前面的错误

  • 一般建议,Promise对象后面要跟catch方法这样可以处理Promise后面发生的错误

finally()方法

    //什么时候执行
        //当Promise状态发生变化时,不论如何都会执行,不变化不执行
        new Promise((resolve, reject) => {
            // resolve(123);
            reject('reason');
        }).finally((data) => {
            console.log(data);
        }).catch((err) => {

        })

        //本质:finally本质上是then()的特例
        //上面的代码等价于
        new Promise((resolve, reject) => {
                // resolve(123);
                reject('reason');
            })
            .then((result) => {
                return result;
            }, err => {
                return new Promise((resolve, reject) => {
                    reject(err);
                })

            }).catch((err) => {
                console.log(err);
            })

 

Promise.all()

  • Promise.all()关注多个Promise对象的状态变化

  • 传入多个Promise实例,包装成一个新的Promise实例返回值

  • promise.all()的状态变化与所有传入的Promise实例对象状态有关

  • 所有状态变成resolved 最终的状态才会变成resolved

  • 只要有一个状态变成rejected最终的状态才会变成rejected

 

在这里插入图片描述

Promise.race()

  • Promise.race()的状态取决于第一个完成Promise实例的对象

  • 如果第一个完成的成功了,那最终的就成功了,如果第一个完成的失败了 那最终的就失败了

 <script>
        //Promise.race()
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms)
            })
        }

        const p1 = delay(1000).then(() => {
            console.log('p1完成了');
            //  return 'p1'
            return Promise.reject('reason')
        })

        const p2 = delay(2000).then(() => {
            console.log('p2完成了');
            return 'p2'
                // return Promise.reject('reason')
        })


        //Promise.race()的状态取决于第一个完成Promise实例的对象
        //如果第一个完成的成功了,那最终的就成功了,如果第一个完成的失败了 那最终的就失败了

        const racePromise = Promise.race([p1, p2])
        racePromise.then(data => {
            console.log(data);
        }, err => {
            console.log(err);
        })
    </script>

Promise.allSettled()

 <script>
        //Promise.race()
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms)
            })
        }

        const p1 = delay(1000).then(() => {
            console.log('p1完成了');
            return 'p1'
                //return Promise.reject('reason')
        })

        const p2 = delay(2000).then(() => {
                console.log('p2完成了');
                //  return 'p2'
                return Promise.reject('reason')
            })
            // Promise.allSettled()的状态与传入的promise状态无关
            //永远都是成功的状态
            //它只会忠实的记录下各个Promise的表现
        const allSettledPromise = Promise.allSettled([p1, p2])
        allSettledPromise.then(data => {
            console.log('succ', data);
        })
    </script>

十七、Module的两种导入和导出

export default 导出和对应的 import 导入
export 导出和对应的 import 导入

//module.js
const age = 20;
export default age;
 <script type="module">
           //一个模块没有导出,也可以将其导入 
         //被导入的代码都会执行一遍,也仅仅会执行一遍
        //使用export default可以随便起名(有语义化) 
       //一个模块只能有一个export default
        import age from './module.js'; console.log(age); //基本用法
    </script>
export function fn() {}
export class className {}
export const age1 = 19
       导入导出时起别名:
         export {fu as func,className as Person,age}  from './module2.js'
        整体导入:会导入所有的输出,包括export default导出的
        import * as obj from './module.js'
<script type="module">
        import { age } from './module2.js'; 
        console.log(age); 
        import { fn } from './module2.js';
         import { className } from './module2.js'; 
         console.log(className); 
         import { age1 } from './module2.js'; 
         console.log(age);
    </script>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

 十八、class类

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;

内容:
class 声明类;
constructor 定义构造函数初始化;
extends 继承父类;
super 调用父级构造方法;
static 定义静态方法和属性;
父类方法可以重写;

 // class静态成员

        // ES5写法
        // function Phone() {}
        // Phone.name = "手机";

        // Phone.change = function () {
        //     console.log("我可以改变世界!");
        // }
        // let nokia = new Phone();
        // console.log(nokia.name); // undefined
        // // nokia.change();
        // // 报错:Uncaught TypeError: nokia.change is not a function
        // Phone.prototype.color = "黑色";
        // console.log(nokia.color); // 黑色
        // console.log(Phone.name);
        // Phone.change();

        // 注意:实例对象和函数对象的属性是不相通的

        // ES6写法
        class Phone {
            // 静态属性,只有类有,实例对象是没有的
            static name = "手机";
            static change() {
                console.log("我可以改变世界!");
            }
        }
        let nokia = new Phone();
        console.log(nokia.name);
        console.log(Phone.name);
        Phone.change();

ES5构造函数实现继承

 // ES5构造函数继承
        // 手机
        function Phone(brand, price) {
            this.brand = brand;
            this.price = price;
        }
        Phone.prototype.call = function () {
            console.log("我可以打电话!");
        }
        // 智能手机
        function SmartPhone(brand, price, color, size) {
            Phone.call(this, brand, price);
            this.color = color;
            this.size = size;
        }

        // 设置子级构造函数的原型
        SmartPhone.prototype = new Phone;
        SmartPhone.prototype.constructor = SmartPhone;

        // 声明子类的方法
        SmartPhone.prototype.photo = function () {
            console.log("我可以拍照!");
        }
        SmartPhone.prototype.game = function () {
            console.log("我可以玩游戏!");
        }
        const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
        console.log(chuizi);
        chuizi.call();
        chuizi.photo();
        chuizi.game();

十九、ES6class类继承

class中的getter和setter设置

  // class中的getter和setter设置

        class Phone {

            get price() { //当price这个属性被读取,会执行这个函数
                console.log("价格属性被读取了!");
                // 返回值
                return 123;
            }
            set price(value) {//当price这个属性被修改,会执行这个函数
                console.log("价格属性被修改了!");
            }
        }

        // 实例化对象
        let s = new Phone();

        console.log(s.price); // 返回值
        s.price = 2999;

二十、async 和 await

async 函数

  • async 函数的返回值为promise对象;

  • promise 对象的结果由async 函数执行的返回值决定


// async函数:异步函数
async function fn() {
    // return 123; // 返回普通数据
    // 若报错,则返回的Promise对象也是错误的
    // throw new Error("出错啦!");
    // 若返回的是Promise对象,那么返回的结果就是Promise对象的结果
    return new Promise((resolve, reject) => {
        // resolve("成功啦!");
        reject("失败啦!");
    })
}
const result = fn();
// console.log(result); // 返回的结果是一个Promise对象
// 调用then方法
result.then(value => {
    console.log(value);
}, reason => {
    console.warn(reason);
});

await 表达式

  • await 必须写在 async 函数中;

  • await 右侧的表达式一般为 promise 对象;

  • await 返回的是 promise 成功的值;

  • await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理;

// async函数 + await表达式:异步函数
 
// 创建Prmise对象
const p = new Promise((resolve,reject)=>{
    resolve("成功啦!");
})
async function fn(){
    // await 返回的是 promise 成功的值
    let result = await p;
    console.log(result); // 成功啦!
}
fn();

 async 和 await 结合发送ajax请求

// async 和 await 结合发送ajax请求
   function sendAjax(url) {
       return new Promise((resolve, reject) => {
           // 1、创建对象
           const x = new XMLHttpRequest();
           // 2、初始化
           x.open("GET", url);
           // 3、发送
           x.send();
           // 4、事件绑定
           x.onreadystatechange = function () {
               if (x.readyState == 4) {
                   if (x.status >= 200 && x.status <= 299) {
                       // 成功
                       resolve(x.response);
                   } else {
                       // 失败
                       reject(x.status);
                   }
               }
           }
       });
   }
   async function main() {
       let result = await sendAjax("https://api.apiopen.top/getJoke");
       console.log(result);
   }
   main();

  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值