ES6部分基础解析

ES6

let和const

  • let
    • let声明的变量不进行变量提升
    • let声明的变量在同一个作用域下不能重名
    • 代码执行之前,会进行过滤如果重名就会报错 (全局代码执行之前,函数即使不执行函数里也进行过滤如果重名就会报错)
    • let声明的变量只在当前作用域有效(能往上级作用域查找)
    • let可以解决暂时性死区
  • const
    • 定义常量:不可以被修改
    • const定义常量必须赋值
  • let和const没有变量提升,var有变量提升
  • let和const不能重复声明,var可以
  • var在全局作用域下声明变量会给window增加键值对,let不会
暂时性死区
		// console.log(a)
        // console.log(typeof a) // 'undefined'
		// var a=12;

        console.log(typeof a)//Cannot access 'a' before initialization
        //无法在初始化之前访问'a'
        let a = 12
        // ES6让js变得更加严谨

块级作用域

  • if else for while try catch -->块级作用域
  • 块级作用域,和形参重名,函数赋值不能影响外面
  • 在块级作用域下var和function是不可以重名的
//  
		console.log(num);// undefined
        console.log(fn);// undefined
        if([]){
            // 只要进到当前if条件中,会立即对fn进行赋值;
            // 支持es6的浏览器,会把这个if的大阔号解析成一个块级作用域;
            fn()
            var num=100;
            function fn(){console.log("a")}
        }
        console.log(fn);//fn(){console.log("a")}
//
        console.log(fn);// undefined
        for(var i=0;i<2;i++){
            function fn(){}
        }
        console.log(fn);//function fn(){}
//
        console.log(f); //undefined
        let i = 0;
        while (i < 1) {
            i++
            function f() {

            }
        }
        console.log(f); //function fn(){}
  • 块级作用域,和形参重名,函数赋值不能影响外面
            var b = {
            a: "hello"
        };
        function fn(b) {
            b.a = "world";
            if (true) {
                function b(){}//块级作用域,和形参重名,函数赋值不能影响外面
            }
            console.log(b);//{a: "world"}

        }
        fn(b)
  • 在块级作用域下var和function是不可以重名的
       //  在块级作用域下var和function是不可以重名的
        if (!("aa" in window)) {
            var aa = 1;

            function aa() {
                console.log(aa)
            }
        }
        console.log(aa);//报错Identifier 'aa' has already been declared  已声明标识符“aa”//


for循环

  • for循环;let定义的变量位置是一个父作用域,每一轮循环都是一个子作用域;每一个子作用域不会销毁,并且每一个子作用域存储了变量i;

箭头函数

  • 箭头函数没有this
    • 箭头函数没有this,要是在箭头函数里使用this,就看他上一级作用域的this,【上一级作用域中this是谁,箭头函数中this就是谁】,不能用call更改,不能被new
    • 不能被new,没有prototype属性,不可以作为构造函数。
    • es6规定箭头函数就是函数,class就是类,箭头函数不能作为类
    • 箭头函数中没有arguments,用剩余运算符代替
    • 给函数的形参赋默认值(普通函数和箭头函数都可以)
    • 箭头函数不能作为generator函数;
  • 写法
    • 如果只有一个形参,可以去掉小括号
    • 如果只有return一行代码可以省略return和大括号
    • 如果return的是一个对象你要是省略的话,就给对象加小括号
        //    let m;
        //    const y;
        // =====================================================
        // let fn = () => {
        //     console.log(this)
        // }
        // fn()
        // let obj = {
        //     name:3,
        //     fn:function(){
        //         // this->obj
        //         return ()=>{
        //             console.log(this)
        //         }
        //     }
        // }
        // obj.fn()()
        // let fn = (w)=>{
        //     return {name:3}
        // }
        // let fn1 = w=>({name:3})
        // console.log(fn1())
        // 箭头函数
        // 1.箭头函数形式
        // 1. 在()和{}之间换成了=>,去掉了function;
        // 2. 如果箭头函数中只有一个形参,可以省略小括号
        // 3. 如果{}只有一条语句可以省略大括号;
        // 4. 如果箭头后面只有一个值,这个值就是函数的返回值;省略了{}和return;
        // 5. 如果返回一个对象,并且去掉{}和return,需要在对象的外面加上();
            
        // 2.箭头函数执行
        function f(){}
        var fn = function(num){}
        fn()
        let f  = num =>({num});
        var d = f(1)
        console.log(d);

        function fn(a) {
            return function (b) {
                return function (c) {
                    return a + b + c;
                }
            }
        }
        let fn = a => b => c => a + b + c;
        fn(1)(2)(3)

class的语法(class自定义类)

    // function Fn(){

    // };
    
    //let fn=()=>{};// 不能作为构造函数;
    // class  : class 类名  {}
    // var a = 1;
    // var obj = {
    //     a,
    //     fn(){// 这不是一个箭头函数;
    //         console.log(100);
            
    //     }
    // }
    // obj.fn();
    // console.log(obj);

    class Bar{ // 这既不是一个函数的{},也不是对象的{};
        constructor(x,y){
            // 这个的代码就相当于函数体中的代码;
            // 这里面可以新增实例私有属性
            //this.x=x;
           this.y=y;
        }
        // 在原型上新增方法;
        getX(){// 这不是箭头函数
            console.log("X");
        }
        getY(){
            console.log("Y");
        }
        static x=1// static可以给Bar类新增私有属性
        y=2// 在给实例新增私有属性
    }
    console.log(typeof Bar)
    //Bar.prototype.x=100;
    console.dir(Bar);
    let a =  new Bar(100,200);
    console.log(a);
    // {x:1,arguments:null,caller:null,prototype:{}}
    // Bar
    
    // console.log(a);
    //var b = Bar();
    //console.log(b);


//     function Fn(){
          // var num=1;
//        // this.x=num;
//     }
//     Fn.prototype.getX=function(){

//     }
//     Fn.x=1;// 
//     let f = new Fn;
//     console.log(f.x) 
 		
		// function Fn(){
    //     this.s = 5;
    // }
    // Fn.prototype.getX = function(){
    // }
    // Fn()
    // new Fn    

class Fn {
        // 这里边放的是实例的私有属性
        constructor (n,m){
            this.s = n
        }
        // 直接在外边写就是给实例添加公有属性
        getX(){
            console.log(111)
        }
        r = 4 // 如果用等号赋值,那就是给实例增加私有属性

        static m = 10 // 把Fn当做对象,增加键值对
    }
    Fn.prototype.getY = function(){console.log(222)}
    let f = new Fn(3);
    // Fn() 报错
    console.log(f)
    console.log(Fn.prototype)
    console.dir(Fn)

class继承
  // ES6中class创造出来的类不能当做普通函数执行
        class A {
            constructor(q) {
                this.x = q;
            }
            getX() {
                console.log(this.x)
            }
        }
        // ES6中的继承
        class B extends A {
            constructor(name) {
                // 子类继承父类,可以不写constructor,但是你要是一旦写了,
              那在constructor里第一句话就要写super()
                // 你要是不写constructor,那浏览器会默认创建一个constructor(...arg){
                //     super(...arg)
                // }
                super(200) // A.call(this, 200) 把父类当做普通函数执行,给方法传递参数,
              让方法中的this是子类的实例

                this.y = 100;
            }
            getX() {
                console.log(this.y)
            }
        }
        B.prototype = Object.create(A.prototype); // class定义的类不能改原型重定向
        let f = new B(100);
        console.log(f)
-----------------------------------------------------------
          //class继承
                  class A{
            constructor(){
                this.x =1;
            }
            getX=()=>{
                // 这是一个普通函数
            }
            getY(){
                // 这是一个公有的属性
            }
        }
        
        let a = new A;
        // B的prototype中的__proto指向A的原型
        // class 继承既继承A的私有属性,又能继承其公有属性;
        class B extends A{
            constructor(a){
                super();// super;
                this.z=a;
            }
            getZ(){

            }
        }
        let b = new B(1);
        console.log(b);

普通对象

  • 普通对象里的属性名和属性值一样时,只写一个就可以。
  {
                name,
                age,
                sex
            }

函数参数

  • 在ES6中,形参可以被赋默认值;
  • 如果有实参,并且不是undefined,那么实参会将默认值覆盖;
  • 如果使用函数默认值时,在此上下文中不允许重复参数名
        function fn(x,y={}){
            console.log(x,y); 
        }
        fn("a",null); 
------------------------------------------
        // 如果使用函数默认值时,不允许有重名的参数
        function fn(x,x,y=1){
            console.log(x);//Duplicate parameter name not allowed in this context
  //在此上下文中不允许重复参数名
        }
        fn(1,2,3)

解构赋值

  • 在ES6中,按照一定的模式,从数组或对象中给变量赋值
  • 在数组中,解构是一一对应的;如果只有变量,右边没有对应的值,那么默认解构出undefined
  • 被解构的值一定是可遍历的
		let [a,b,c,d]=[100,200,300];
		console.log(a)//100
		console.log(b)//200
		console.log(c)//300
		console.log(d)//undefined
		let a=1;//报错
  • 解构赋值允许赋默认值
		let [a,b=1]=[1]
    console.log(b)//1

对象的解构赋值
  • 对象是按照对象的属性名进行匹配和解构的,必须保持属性名一致
  • 如果等号右边没有对应的属性值,解构出undefined
  • 如果右面严格等于undefined,那么存储默认值
      let {name,age}={name:"zhufeng",age:10};
      console.log(name)//"zhufeng"

			function fn(){}
			 
			//fn就是属性名,就是fn;右边是属性值,fn所代表的值;
			//如果属性名和属性值相同可以省略一个
			var obj={fn}
      -------------------------------------------
        var obj = {
	          a: {
	
	            }
        }
        let {
           a:n   //n是别名,只能拿到属性值
        } = obj;
        console.log(n);

字符串的解构赋值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

函数的参数解构赋值
  • 参数的解构:如果有实参,那么实参的值一定覆盖默认的值
  • 如果没有实参,形参也没有对应的要解构的值,这样就会报错
  • 如果没有实参,形参有对应的要解构的值,那么会进行解构默认的对象
		function fn([x,y]){
    	console.log(x)
      console.log(y)
    }
		fn([1,2])
-----------------------------------
     function move({
            x,
            y
        }) {
            return [x, y];
        }
        console.log(move({
            x: 3,
            y: 8
        }));// [3, 8]

在这里插入图片描述

…运算符

  • 收缩运算符(一般用在函数的形参)
  • 展开运算符(一般用在函数的实参)
  • 拓展运算符
    // ...运算符
    // function fn(...g){
    //     console.log(g)
    // }
    // fn(...[12,34,46,67,78,132,32,34])
    // let ary = [12,23,45,66];
    // // let n = ary[0]
    // // let m  =[]
    // // 前提是等号的左边和右边结构的一样
    // let [m,...a] = ary;
    // console.log(m,a) // 12 , [23, 45, 66]

    // // 我想拿到数组的第一项和最后一项
    // // let [x,,,s] = ary;
    // console.log(x,s)
        // let ary = [12,234,45,[23,435]];
        // console.log(ary[3][1]) // 435
        // let [m,,,[,x]] = ary
        // console.log(m,x) // 12, 435

    // 普通对象的解构赋值
    // let obj = {
    //     name:2,
    //     age:3
    // }
    // let obj1 = {...obj}
    // console.log(obj1) // 克隆obj
    // 在左边的对象里定义变量名,如果这个变量名在右边的对象里有对应的属性名,
那就把对应的属性值赋值给左边的变量名.
    // 如果右边没有这个属性名就是undefined
    // 还可以给左边的变量赋默认值
    // let {name,age,we = 9} = obj;
    // console.log(name, age,we);
    // let ary = [1,2,3];
    // let  [m, , , r = 6] = ary
    // console.log(m,r)
    
    // let obj = {
    //     name:3,
    //     age:4
    // }

    // // name:haha  
    // // 创建一个haha变量名,把name对应的值赋值给他
    // let {
    //     name:haha
    // } = obj
    // console.log(haha)

    let obj = {
        name:'erYa',
        age:18,
        friends:['xioaHua', 'gouDan']
    }
    let {friends:[,s]} = obj
    console.log(s) // 'gouDan'

扩展运算符

可以将对象展开,也可以将数组展开

		let arr=[12,2,3,45]
    let ar1r=[120,200,300,450]
    console.log(arr.concat(arr1))
    console.log(...arr,...arr1)

				var obj={name:100}
        var obj1={age:200}
        console.log({...obj,...obj1})

剩余运算符
				//放到参数位置,只能作为最后一个形参
        function sum(m,...ary){//将多余的值收缩成一个数组
            console.log(m)
            console.log(ary)
        }
        sum(10,2,3,4,5,7)

Set数据结构

  • Set 是一种数据结构,不是一种数据类型;
    • Set 数据中不能有重复的值;
    • Set 是一个构造函数;
    • Set传入的实参必须是可遍历的结构;数组 类数组 对象;
    • Set实现数组去重
        // 数组去重
        // var  ary=[12,45,66,34,56,34,45]; 
        // let s = new Set();
        // // 向set数据结构中加值;
        // s.add(100);
        // s.add(100);
        // console.log(typeof s);// "object"
        // console.log(s);

        // 数组去重 12种
        // Set传入的实参必须是可遍历的结构;数组 类数组  对象;
        // var  ary=[12,45,66,34,56,34,45];
        // let s = new Set(ary);
        // console.log(s);

        // add  
        // delete 
        // has :是否含有某一个set成员,返回布尔值
        // clear: 清空set成员;

Map数据结构

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false
------------------------------
const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

函数

generator函数

    <script>
        // generator函数:状态机
        // 1.function 和函数名之间有一个*;
        // 2.函数体内部使用了yield表达式,来定义函数体内部的状态;
        // generator 函数是分段执行的,yield是暂停的标记,next是恢复执行;

        function* fn(){
            console.log(100);
            yield "hello";
            console.log(200);
            yield "world";
            console.log(300);
            return 600;
        }
        let f = fn();// fn的返回值是一个指向指针的对象
        let f1=f.next();// 让当前的状态切换到下一个指针
        console.log(f1);// {value: "hello", done: false}
        let f2 = f.next();
        console.log(f2);
        let f3 = f.next();
        console.log(f3);
        let f4 =f.next()
        console.log(f4);  


100
VM262:11 {value: "hello", done: false}
VM262:4 200
VM262:13 {value: "world", done: false}
VM262:6 300
VM262:15 {value: 600, done: true}
VM262:17 {value: undefined, done: true}

    
    </script>

async函数

    <script>
        // generator *=>async   yield => await
        // async函数: 有内置的执行器;
        // async : 函数中有异步的操作;async函数默认返回一个promise实例
        // await : 等待紧跟在后面的表达式需要等待的结果;
        // await 下面代码是异步的;并且是一个微任务;await后面跟着代码是同步的;

        // 异步任务分为宏任务和微任务;当主任务队列执行完成,需要执行异步任务,
      异步任务先找到里面的微任务,按顺序执行,微任务执行完成,再去执行宏任务;
        // setTimeout(()=>{
        //     console.log(300);
        // },0)
        // function fn1(){
        //     console.log(100);
        //     return 100;
        // }
        // async function fn(){
        //    let s =  await fn1();
        //    console.log(s);
        //    console.log(200);
        // }
        // let result = fn();
        // console.log(result);

        function fn1(){
            // 当函数中返回一个promise实例时
            return new Promise(function(resolve,reject){
                resolve("放假了");
            })  
        }

        function fn2(){
            return new Promise(function(resolve,reject){
                resolve();
            })
        }
        async function fn(){
           let s =  await fn1();
           // 1.如果fn1中返回一个promise实例,那么await下面的代码都是fn1中返回的promise实例then的
          成功回调中的代码;
           // 2.await函数的返回值s就是上一个promise实例中resolve传递的实参;
           console.log(s);
           console.log(200);
           let a = await fn2();
           console.log(666);
        }
        fn();


        // 异步的请求 
        function getData(url){
            return axios.get(url);
        }

        async function fn(){
            // 将异步的代码变成同步;
            let data= await getData("/list");
            for(let i =0;i<data.length;i++){

            }
        }
    </script>

引用数据类型

类数组转数组

Array.from

  • 将类数组集合转成数组(元素集合,arguments)set和map的数据结构
				Array.from 将类数组集合转成数组(元素集合,arguments)set和map的数据结构
        function s(){
            // let a=Array.from(arguments)
            // console.log(a)
            let a=[...arguments]
            console.log(a)
        }
        s(1,2,3,4)

Array.of

将一组数转成数组

        var a=Array.of(1,2,3)
        console.log(a)

Object.assign()的用法

  • Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。
let targetObj1 = { a: 1 };
        let sourceObj1 = { b: 1 };
        let sourceObj11 = { c: 3 };
        Object.assign(targetObj1, sourceObj1, sourceObj11);
        console.log(targetObj1);
--------------------------------------
 function anonymous(content = '', options = {}) {
		//=>参数初始化
		/* 
			Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。
		*/
		options = Object.assign({
			title: '系统温馨提示',
			confirm: false,
			handled: null
		}, options);
		return new Dialog(content, options);
	}

ES5 数据拦截(Object.defineProperty)

        //Object.defineProperty 劫持对象中某个属性的操作;
        //全局变量也是给window设置一个全局属性

        // var i=0;
        // Object.defineProperty(window, "a", {
        //     get() {
        //         //获取window.a的时候触发
        //         return  ++i;
        //     },
        //     set() {
        //         //给window.a设置属性值得时候触发
        //         console.log(2);
        //     }
        // })
        // if (a == 1 && a == 2 && a == 3) {
        //     console.log("ok");
        // }

defineProperty


对一个对象的某个属性的定义

// Object.defineProperty:对一个对象中某个属性的定义(处理)
let obj = {
    name: 'ls',
    age: 10
};
// 设置属性的 GETTER、SETTER:我们可以在 GETTER、SETTER 中监听当前属性设置和获取的时候干什么 => 
// 这也是VUE 2.0 响应式数据(双向数据绑定)实现的原理,VUE 3.0采用的是 PROXY
Object.defineProperty(obj, 'name', {
    get() {
        console.log('GETTER');
        return 'HELLO WORLD';
    },
    set(value) {
        console.log('SETTER', value);
    }
});
// console.log(obj.name);
obj.name = '哈哈哈~~';
//
Object.defineProperty(obj, 'name', {
    value: '哈哈哈哈哈',
    // 是否允许当前的属性被删除
    configurable: true,
    // 是否为可枚举的属性
    enumerable: true,
    // 是否允许当前属性被修改
    writable: true
});

es6 数组实例的 fill()

fill方法使用给定值,填充一个数组。
fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置

['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

字符串

模板字符串(``)

       //  let ss = 25;
        //  let str = '<li>'+ss+'</li>';
        // '<li><span>'+ss+'</span><span>'+ss+'</span></li>'
        // let str = `<li><span>${ss}</span><span>${ss}</span></li>`

实例方法:padStart(),padEnd()

  • ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
  • 如果省略第二个参数,默认使用空格补全长度。
'x'.padStart(4) // '   x'
'x'.padEnd(4) // 'x   '
  • 用来补零
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值