詳細介紹JavaScript提高學習之ES6

2022-02-07 19:02:10
本篇文章給大家帶來了關於es6的相關知識,其中包括嚴格模式、高階函數以及閉包和遞迴等相關問題,希望對大家有幫助。

目錄總覽

在這裡插入圖片描述

1、嚴格模式

  • JavaScript 除了提供正常模式外,還提供了嚴格模式
  • ES5 的嚴格模式是採用具有限制性 JavaScript 變體的一種方式,即在嚴格的條件下執行 JS 程式碼
  • 嚴格模式在IE10 以上版本的瀏覽器才會被支援,舊版本瀏覽器會被忽略
  • 嚴格模式對正常的JavaScript語意做了一些更改:
    • 消除了Javascript 語法的一些不合理、不嚴謹之處,減少了一些怪異行為
    • 消除程式碼執行的一些不安全之處,保證程式碼執行的安全
    • 提高編譯器效率,增加執行速度
    • 禁用了在 ECMAScript 的未來版本中可能會定義的一些語法,為未來新版本的 Javascript 做好鋪墊。比如一些保留字如:class, enum, export, extends, import, super 不能做變數名

1.1、開啟嚴格模式

  • 嚴格模式可以應用到整個指令碼個別函數中。
  • 因此在使用時,我們可以將嚴格模式分為為指令碼開啟嚴格模式為函數開啟嚴格模式兩種情況

1.1.2、為指令碼開啟嚴格模式

  • 為整個指令碼檔案開啟嚴格模式,需要在所有語句之前放一個特定語句

  • "use strict"'use strict'

<script>
    'user strict';
	console.log("這是嚴格模式。");</script>

因為"use strict"加了引號,所以老版本的瀏覽器會把它當作一行普通字串而忽略。

有的 script 基本是嚴格模式,有的 script 指令碼是正常模式,這樣不利於檔案合併,所以可以將整個指令碼檔案放在一個立即執行的匿名函數之中。這樣獨立建立一個作用域而不影響其他 script 指令碼檔案。

<script>
	(function (){
    	'use strict';
    	 var num = 10;
    	 function fn() {}
	})();   </script>

1.1.2、為函數開啟嚴格模式

  • 若要給某個函數開啟嚴格模式,需要把"use strict"'use strict'宣告放在函數體所有語句之前
<body>
    <!-- 為整個指令碼(script標籤)開啟嚴格模式 -->
    <script>
        'use strict';
        //   下面的js 程式碼就會按照嚴格模式執行程式碼
    </script>
    <script>
        (function() {
            'use strict';
        })();
    </script>
    <!-- 為某個函數開啟嚴格模式 -->
    <script>
        // 此時只是給fn函數開啟嚴格模式
        function fn() {
            'use strict';
            // 下面的程式碼按照嚴格模式執行
        }

        function fun() {
            // 裡面的還是按照普通模式執行
        }
    </script></body>
  • "use strict" 放在函數體的第一行,則整個函數以 "嚴格模式"執行。

2、嚴格模式中的變化

  • 嚴格模式對JavaScript的語法和行為,都做了一些改變

2.1、變數規定

  • 在正常模式中,如果一個變數沒有宣告就賦值,預設是全域性變數
  • 嚴格模式禁止這種用法,變數都必須先用var 命令宣告,然後再使用
  • 嚴禁刪除已經宣告變數,例如,``delete x` 語法是錯誤的
<body>
    <script>
        'use strict';
        // 1. 我們的變數名必須先宣告再使用
        // num = 10;
        // console.log(num);
        var num = 10;
        console.log(num);
        // 2.我們不能隨意刪除已經宣告好的變數
        // delete num;
    </script></body>

2.2、嚴格模式下this指向問題

  1. 以前在全域性作用域函數中的this指向window物件
  2. 嚴格模式下全域性作用域中函數中的thisundefined
  3. 以前建構函式時不加 new 也可以呼叫,當普通函數,this指向全域性物件
  4. 嚴格模式下,如果建構函式不加 new 呼叫,this指向的是 undefined ,如果給它賦值,會報錯
  5. new 範例化的建構函式指向建立的物件範例
  6. 定時器this 還是指向window
  7. 事件、物件還是指向呼叫者
<body>
    <script>
        'use strict';
		//3. 嚴格模式下全域性作用域中函數中的 this 是 undefined。
        function fn() {
            console.log(this); // undefined。

        }
        fn();
        //4. 嚴格模式下,如果 建構函式不加new呼叫, this 指向的是undefined 如果給他賦值則 會報錯.
        function Star() {
            this.sex = '男';
        }
        // Star();
        var ldh = new Star();
        console.log(ldh.sex);
        //5. 定時器 this 還是指向 window 
        setTimeout(function() {
            console.log(this);

        }, 2000);
        
    </script></body>

2.3、函數變化

  1. 函數不能有重名的引數
  2. 函數必須宣告在頂層,新版本的JavaScript會引入「塊級作用域」(ES6中已引入)。為了與新版本接軌,不允許在非函數的程式碼塊內宣告函數
<body>
    <script>
        'use strict';
        // 6. 嚴格模式下函數裡面的引數不允許有重名
        function fn(a, a) {
           console.log(a + a);

        };
        // fn(1, 2);
        function fn() {}
    </script></body>

3、高階函數

  • 高階函數是對其他函數進行操作的函數,它接收函數作為引數將函數作為返回值輸出

接收函數作為引數

<body>
    <p></p>
    <script>
        // 高階函數- 函數可以作為引數傳遞
        function fn(a, b, callback) {
            console.log(a + b);
            callback && callback();
        }
        fn(1, 2, function() {
            console.log('我是最後呼叫的');

        });

    </script></body>

將函數作為返回值

<script>
    function fn(){
        return function() {}
    }</script>
  • 此時 fn 就是一個高階函數
  • 函數也是一種資料型別,同樣可以作為引數,傳遞給另外一個引數使用。最典型的就是作為回撥函數
  • 同理函數也可以作為返回值傳遞回來

4、閉包

4.1、變數作用域

變數根據作用域的不同分為兩種:全域性變數和區域性變數

  1. 函數內部可以使用全域性變數
  2. 函數外部不可以使用區域性變數
  3. 當函數執行完畢,本作用域內的區域性變數會銷燬。

4.2、什麼是閉包

閉包指有權存取另一個函數作用域中的變數的函數

簡單理解:一個作用域可以存取另外一個函數內部的區域性變數

<body>
    <script>
        // 閉包(closure)指有權存取另一個函數作用域中變數的函數。
        // 閉包: 我們fn2 這個函數作用域 存取了另外一個函數 fn1 裡面的區域性變數 num
        function fn1() {		// fn1就是閉包函數
            var num = 10;
            function fn2() {
                console.log(num); 	//10
            }
            fn2();
        }
        fn1();
    </script></body>

4.3、在chrome中偵錯閉包

  1. 開啟瀏覽器,按 F12 鍵啟動 chrome 偵錯工具。

  2. 設定斷點。

  3. 找到 Scope 選項(Scope 作用域的意思)。

  4. 當我們重新重新整理頁面,會進入斷點偵錯,Scope 裡面會有兩個引數(global 全域性作用域、local 區域性作用域)。

  5. 當執行到 fn2() 時,Scope 裡面會多一個 Closure 引數 ,這就表明產生了閉包。

在這裡插入圖片描述

4.4、閉包的作用

  • 延伸變數的作用範圍
<body>
    <script>
        // 閉包(closure)指有權存取另一個函數作用域中變數的函數。
        // 一個作用域可以存取另外一個函數的區域性變數 
        // 我們fn 外面的作用域可以存取fn 內部的區域性變數
        // 閉包的主要作用: 延伸了變數的作用範圍
        function fn() {
            var num = 10;
            return function() {
                console.log(num);
            }
        }
        var f = fn();
        f();
    </script></body>

4.5、閉包練習

4.5.1、點選li輸出索引號

<body>
    <ul class="nav">
        <li>榴蓮</li>
        <li>臭豆腐</li>
        <li>鯡魚罐頭</li>
        <li>大豬蹄子</li>
    </ul>
    <script>
        // 閉包應用-點選li輸出當前li的索引號
        // 1. 我們可以利用動態新增屬性的方式
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i;
            lis[i].onclick = function() {
                // console.log(i);
                console.log(this.index);

            }
        }
        // 2. 利用閉包的方式得到當前小li 的索引號
        for (var i = 0; i < lis.length; i++) {
            // 利用for迴圈建立了4個立即執行函數
            // 立即執行函數也成為小閉包因為立即執行函數裡面的任何一個函數都可以使用它的i這變數
            (function(i) {
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);

                }
            })(i);
        }
    </script></body>

在這裡插入圖片描述

4.5.2、定時器中的閉包

<body>
    <ul class="nav">
        <li>榴蓮</li>
        <li>臭豆腐</li>
        <li>鯡魚罐頭</li>
        <li>大豬蹄子</li>
    </ul>
    <script>
        // 閉包應用-3秒鐘之後,列印所有li元素的內容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML);
                }, 3000)
            })(i);
        }
    </script></body>

在這裡插入圖片描述

5、遞迴

如果一個函數在內部可以呼叫其本身,那麼這個函數就是遞迴函數

簡單理解: 函數內部自己呼叫自己,這個函數就是遞迴函數

由於遞迴很容易發生"棧溢位"錯誤,所以必須要加退出條件 return

<body>
    <script>
        // 遞迴函數 : 函數內部自己呼叫自己, 這個函數就是遞迴函數
        var num = 1;

        function fn() {
            console.log('我要列印6句話');

            if (num == 6) {
                return; // 遞迴裡面必須加退出條件
            }
            num++;
            fn();
        }
        fn();
    </script></body>

6、淺拷貝和深拷貝

  1. 淺拷貝只是拷貝一層,更深層次物件級別的只拷貝參照
  2. 深拷貝拷貝多層,每一級別的資料都會拷貝
  3. Object.assign(target,....sources) ES6新增方法可以淺拷貝

6.1、淺拷貝

// 淺拷貝只是拷貝一層,更深層次物件級別的只拷貝參照var obj = {
    id: 1,
    name: 'andy',
    msg: {
        age: 18
    }};var o = {}for(var k in obj){
    // k是屬性名,obj[k]是屬性值
    o[k] = obj.[k];}console.log(o);// 淺拷貝語法糖Object.assign(o,obj);

6.2、深拷貝

// 深拷貝拷貝多層,每一級別的資料都會拷貝var obj = {
    id: 1,
    name: 'andy',
    msg: {
        age: 18
    }
    color: ['pink','red']};var o = {};// 封裝函數function deepCopy(newobj,oldobj){
    for(var k in oldobj){
        // 判斷屬性值屬於簡單資料型別還是複雜資料型別
        // 1.獲取屬性值   oldobj[k]
        var item = obldobj[k];
        // 2.判斷這個值是否是陣列
        if(item instanceof Array){
            newobj[k] = [];
            deepCopy(newobj[k],item)
        }else if (item instanceof Object){
              // 3.判斷這個值是否是物件
            newobj[k] = {};
            deepCopy(newobj[k],item)
        }else {
            // 4.屬於簡單資料型別
            newobj[k] = item;
            
        } 
    }}deepCopy(o,obj);

7、 正規表示式

正規表示式是用於匹配字串中字元組合的模式。在JavaScript中,正規表示式也是物件。

正則表通常被用來檢索、替換那些符合某個模式(規則)的文字,例如驗證表單:使用者名稱表單只能輸入英文字母、數位或者下劃線, 暱稱輸入框中可以輸入中文(匹配)。此外,正規表示式還常用於過濾掉頁面內容中的一些敏感詞(替換),或從字串中獲取我們想要的特定部分(提取)等 。

7.1、特點

  • 實際開發,一般都是直接複製寫好的正規表示式
  • 但是要求會使用正規表示式並且根據自身實際情況修改正規表示式

7.2、建立正規表示式

在JavaScript中,可以通過兩種方式建立正規表示式

  1. 通過呼叫 RegExp 物件的建構函式建立

  2. 通過字面量建立

7.2.1、通過呼叫 RegExp 物件的建構函式建立

通過呼叫 RegExp 物件的建構函式建立

var 變數名 = new RegExp(/表示式/);

7.2.2、通過字面量建立

通過字面量建立

var 變數名 = /表示式/;

註釋中間放表示式就是正則字面量

7.2.3、測試正規表示式 test

  • test()正則物件方法,用於檢測字串是否符合該規則,該物件會返回truefalse,其引數是測試字串
regexObj.test(str)
  • regexObj 寫的是正規表示式
  • str 我們要測試的文字
  • 就是檢測str文字是否符合我們寫的正規表示式規範

範例

<body>
    <script>
        // 正規表示式在js中的使用

        // 1. 利用 RegExp物件來建立 正規表示式
        var regexp = new RegExp(/123/);
        console.log(regexp);

        // 2. 利用字面量建立 正規表示式
        var rg = /123/;
        // 3.test 方法用來檢測字串是否符合正規表示式要求的規範
        console.log(rg.test(123));
        console.log(rg.test('abc'));
    </script></body>

7.3、正規表示式中的特殊在字元

7.3.1、邊界符

正規表示式中的邊界符(位置符)用來提示字元所處的位置,主要有兩個字元

邊界符說明
^表示匹配行首的文字(以誰開始)
$表示匹配行尾的文字(以誰結束)

如果^ 和 $ 在一起,表示必須是精確匹配

// 邊界符 ^ $
var rg = /abc/;   //正規表示式裡面不需要加引號,不管是數位型還是字串型
// /abc/只要包含有abc這個字串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));

var reg = /^abc/;
console.log(reg.test('abc'));   //true
console.log(reg.test('abcd'));	// true
console.log(reg.test('aabcd')); // false

var reg1 = /^abc$/
// 以abc開頭,以abc結尾,必須是abc

7.3.2、字元類

  • 字元類表示有一系列字元可供選擇,只要匹配其中一個就可以了
  • 所有可供選擇的字元都放在方括號內

①[] 方括號

/[abc]/.test('andy');     // true

後面的字串只要包含 abc 中任意一個字元,都返回true

②[-]方括號內部 範圍符

/^[a-z]$/.test()

方括號內部加上-表示範圍,這裡表示a - z26個英文字母都可以

③[^] 方括號內部 取反符 ^

/[^abc]/.test('andy')   // false

方括號內部加上^表示取反,只要包含方括號內的字元,都返回 false

注意和邊界符 ^ 區別,邊界符寫到方括號外面

④字元組合

/[a-z1-9]/.test('andy')    // true

方括號內部可以使用字元組合,這裡表示包含a 到 z的26個英文字母和1到9的數位都可以

<body>
    <script>
        //var rg = /abc/;  只要包含abc就可以 
        // 字元類: [] 表示有一系列字元可供選擇,只要匹配其中一個就可以了
        var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回為true
        console.log(rg.test('andy'));
        console.log(rg.test('baby'));
        console.log(rg.test('color'));
        console.log(rg.test('red'));
        var rg1 = /^[abc]$/; // 三選一 只有是a 或者是 b  或者是c 這三個字母才返回 true
        console.log(rg1.test('aa'));
        console.log(rg1.test('a'));
        console.log(rg1.test('b'));
        console.log(rg1.test('c'));
        console.log(rg1.test('abc'));
        console.log('------------------');

        var reg = /^[a-z]$/; // 26個英文字母任何一個字母返回 true  - 表示的是a 到z 的範圍  
        console.log(reg.test('a'));
        console.log(reg.test('z'));
        console.log(reg.test(1));
        console.log(reg.test('A'));
        // 字元組合
        var reg1 = /^[a-zA-Z0-9_-]$/; // 26個英文字母(大寫和小寫都可以)任何一個字母返回 true  
        console.log(reg1.test('a'));
        console.log(reg1.test('B'));
        console.log(reg1.test(8));
        console.log(reg1.test('-'));
        console.log(reg1.test('_'));
        console.log(reg1.test('!'));
        console.log('----------------');
        // 如果中括號裡面有^ 表示取反的意思 千萬和 我們邊界符 ^ 別混淆
        var reg2 = /^[^a-zA-Z0-9_-]$/;
        console.log(reg2.test('a'));
        console.log(reg2.test('B'));
        console.log(reg2.test(8));
        console.log(reg2.test('-'));
        console.log(reg2.test('_'));
        console.log(reg2.test('!'));
    </script></body>

7.3.3、量詞符

量詞符用來設定某個模式出現的次數

量詞說明
*重複零次或更多次
+重複一次或更多次
?重複零次或一次
{n}重複n次
{n,}重複n次或更多次
{n,m}重複n到m次
<body>
    <script>
        // 量詞符: 用來設定某個模式出現的次數
        // 簡單理解: 就是讓下面的a這個字元重複多少次
        // var reg = /^a$/;


        //  * 相當於 >= 0 可以出現0次或者很多次 
        // var reg = /^a*$/;
        // console.log(reg.test(''));
        // console.log(reg.test('a'));
        // console.log(reg.test('aaaa'));



        //  + 相當於 >= 1 可以出現1次或者很多次
        // var reg = /^a+$/;
        // console.log(reg.test('')); // false
        // console.log(reg.test('a')); // true
        // console.log(reg.test('aaaa')); // true

        //  ?  相當於 1 || 0
        // var reg = /^a?$/;
        // console.log(reg.test('')); // true
        // console.log(reg.test('a')); // true
        // console.log(reg.test('aaaa')); // false

        //  {3 } 就是重複3次
        // var reg = /^a{3}$/;
        // console.log(reg.test('')); // false
        // console.log(reg.test('a')); // false
        // console.log(reg.test('aaaa')); // false
        // console.log(reg.test('aaa')); // true
        //  {3, }  大於等於3
        var reg = /^a{3,}$/;
        console.log(reg.test('')); // false
        console.log(reg.test('a')); // false
        console.log(reg.test('aaaa')); // true
        console.log(reg.test('aaa')); // true
        //  {3,16}  大於等於3 並且 小於等於16
        var reg = /^a{3,6}$/;
        console.log(reg.test('')); // false
        console.log(reg.test('a')); // false
        console.log(reg.test('aaaa')); // true
        console.log(reg.test('aaa')); // true
        console.log(reg.test('aaaaaaa')); // false
    </script></body>

7.3.4、使用者名稱驗證

功能需求:

  1. 如果使用者名稱輸入合法, 則後面提示資訊為 : 使用者名稱合法,並且顏色為綠色
  2. 如果使用者名稱輸入不合法, 則後面提示資訊為: 使用者名稱不符合規範, 並且顏色為綠色

分析:

  1. 使用者名稱只能為英文字母,數位,下劃線或者短橫線組成, 並且使用者名稱長度為 6~16位元.

  2. 首先準備好這種正規表示式模式 /$[a-zA-Z0-9-_]{6,16}^/

  3. 當表單失去焦點就開始驗證.

  4. 如果符合正則規範, 則讓後面的span標籤新增 right 類.

  5. 如果不符合正則規範, 則讓後面的span標籤新增 wrong 類.

<body>
    <input type="text" class="uname"> <span>請輸入使用者名稱</span>
    <script>
        //  量詞是設定某個模式出現的次數
        var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 這個模式使用者只能輸入英文字母 數位 下劃線 短橫線但是有邊界符和[] 這就限定了只能多選1
        // {6,16}  中間不要有空格
        // console.log(reg.test('a'));
        // console.log(reg.test('8'));
        // console.log(reg.test('18'));
        // console.log(reg.test('aa'));
        // console.log('-------------');
        // console.log(reg.test('andy-red'));
        // console.log(reg.test('andy_red'));
        // console.log(reg.test('andy007'));
        // console.log(reg.test('andy!007'));
        var uname = document.querySelector('.uname');
        var span = document.querySelector('span');
        uname.onblur = function() {
            if (reg.test(this.value)) {
                console.log('正確的');
                span.className = 'right';
                span.innerHTML = '使用者名稱格式輸入正確';
            } else {
                console.log('錯誤的');
                span.className = 'wrong';
                span.innerHTML = '使用者名稱格式輸入不正確';
            }
        }
    </script></body>

7.4、括號總結

  1. 大括號 量詞符 裡面面表示重複次數
  2. 中括號 字元集合 匹配方括號中的任意字元
  3. 小括號 表示優先順序
// 中括號 字元集合 匹配方括號中的任意字元
var reg = /^[abc]$/;
// a || b || c
// 大括號 量詞符 裡面表示重複次數
var reg = /^abc{3}$/;   // 它只是讓c 重複3次 abccc
// 小括號 表示優先順序
var reg = /^(abc){3}$/;  //它是讓 abc 重複3次

線上測試正規表示式:https://c.runoob.com/

7.5、預定義類

預定義類指的是某些常見模式的簡寫寫法

預定類說明
\d匹配0-9之間的任一數位,相當於[0-9]
\D匹配所有0-9以外的字元,相當於[ ^ 0-9]
\w匹配任意的字母、數位和下劃線,相當於[A-Za-z0-9_ ]
\W除所有字母、數位、和下劃線以外的字元,相當於[ ^A-Za-z0-9_ ]
\s匹配空格(包括換行符,製表符,空格符等),相當於[\t\t\n\v\f]
\S匹配非空格的字元,相當於[ ^ \t\r\n\v\f]

7.5.1、表單驗證

分析:

1.手機號碼: /^1[3|4|5|7|8][0-9]{9}$/

2.QQ: [1-9][0-9]{4,} (騰訊QQ號從10000開始)

3.暱稱是中文: ^[\u4e00-\u9fa5]{2,8}$

<body>
    <script>
        // 座機號碼驗證:  全國座機號碼  兩種格式:   010-12345678  或者  0530-1234567
        // 正則裡面的或者 符號  |  
        // var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
        var reg = /^\d{3,4}-\d{7,8}$/;
    </script></body>

7.6、正規表示式中的替換

7.6.1、replace 替換

replace()方法可以實現替換字串操作,用來替換的引數可以是一個字串或是一個正規表示式

stringObject.replace(regexp/substr,replacement)
  1. 第一個引數: 被替換的字串或者正規表示式
  2. 第二個引數:替換為的字串
  3. 返回值是一個替換完畢的新字串
// 替換 replacevar str = 'andy和red';var newStr = str.replace('andy','baby');var newStr = str.replace(/andy/,'baby');

7.6.2、正規表示式引數

/表示式/[switch]

switch按照什麼樣的模式來匹配,有三種

  • g: 全域性匹配
  • i:忽略大小寫
  • gi: 全域性匹配 + 忽略大小寫

相關推薦:

以上就是詳細介紹JavaScript提高學習之ES6的詳細內容,更多請關注TW511.COM其它相關文章!