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   '
  • 用來補零
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章