JavaScript筆記(二)

一、JavaScript面向對象

1、類 constructor 構造函數

constructor() 方法是類的構造函數(默認方法),用於傳遞參數,返回實例對象,通過new命令生成實例時,自動調用該方法。如果沒有顯示定義,類內部會自動創建一個constructor()

//語法
class Person {    
    constructor(name,age){  // constructor 構造方法或者構造函數
         this.name = name;
         this.age = age;
    }  
   //添加方法
    say(){    
         console.log(this.name + '你好')
    } 
}

//創建實例
var ldh = new Person('劉德華',18)
ldh.say()
console.log(ldh.name)

 2、繼承

子類可以繼承父類的屬性和方法

class Person {
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    say(){
        console.log(this.name + '你好')
    }
}
class son extends Person{    //子類

}
var ldh = new son('劉德華',18)
ldh.say()
console.log(ldh.name)

3、super 關鍵字

super關鍵字用於訪問和調用對象父類上的函數,可以調用父類的構造函數,也可以調用父類的普通函數

語法:

class Person {
    constructor(name) {
        this.name = name;
    }
}
class son extends Person{  //子類繼承父類
    constructor(name,age) {
        // 注意: 子類在構造函數中使用super, 必須放到 this 前面  (必須先調用父類的構造方法,在使用子類構造方法)
        super(name);  //子類調用父類的constructor(name)
        this.age = age;  //定義子類獨有的屬性
    }
}

案例:

class Person {
    constructor(name) {
        this.name = name;
    }
    SayName(){
        console.log('我的名字是:'+this.name)
    }
}
class son extends Person{  //子類繼承父類
    constructor(name,age) {
        // 注意: 子類在構造函數中使用super, 必須放到 this 前面  (必須先調用父類的構造方法,在使用子類構造方法)
        super(name);  //子類調用父類的constructor(name)
        this.age = age;  //定義子類獨有的屬性
    }
    SayAge(){
        console.log('年齡是:'+this.age)
    }
}
var ldh = new son('劉德華',18)
ldh.SayName()
ldh.SayAge()

二、函數進階

1、this

1.1 函數內 this 的指向問題

這些 this 的指向,是當我們調用函數時確定的。調用方式的不同決定了 this 的指向不同。

 2.2 改變函數內部 this 指向

JavaScript 為我們專門提供了一些函數方法幫我們處理函數內部 this 的指向問題,常用的有bind()、call()、apply()三種方法

(1)call() 方法調用一個對象。簡單理解為調用函數的方式,但是他可以改變函數的 this 指向。

//語法
fun.call(thisArg, arg1, arg2, ...) 

//thisArg:在 fun 函數運行時指定的 this 值
//arg1,arg2:傳遞的其他參數
//返回值就是函數的返回值,因為它就是調用函數
//因此當我們想改變 this 指向,同時想調用這個函數的時候,可以使用 call,比如繼承

(2)apply() 方法調用一個對象

//語法
fun.apply(thisArg, [argsArray])
//thisArg:在fun函數運行時指定的 this 值
//argsArray:傳遞的值,必須包含在數組裡面
//返回值就是函數的返回值,因為它就是調用函數
//因此 apply 主要跟數組有關係,比如使用 Math.max() 求數組的最大值

(3)bind()方法不會調用函數。但是能改變函數內部this指向

//語法
fun.bind(thisArg, arg1, arg2, ...) 
//thisArg:在 fun 函數運行時指定的 this 值
//arg1,arg2:傳遞的其他參數
//返回由指定的 this 值和初始化參數改造的原函數拷貝
//因此當我們只是想改變 this 指向,並且不想調用這個函數的時候,可以使用 bind

三、嚴格模式

1、什麼是嚴格模式

JavaScript除了提供正常模式外,還提供了嚴格模式(strict mode)。ES5 的嚴格模式是採用具有限制性JavaScript變體的一種方式,即在嚴格的條件下運行JS程式碼。

嚴格模式在IE10以上版本的瀏覽器中才會被支援,舊版本瀏覽器中會被忽略。

嚴格模式對正常的JavaScript語義做了一些更改:

(1)消除了Javascript語法的一些不合理、不嚴謹之處。 減少了一些怪異行為。

(2)消除程式碼運行的一些不安全之處,保證程式碼運行的安全

(3)提高編譯器效率,增加運行速度。

(4)禁用了在ECMAScript的未來版本中可能會定義的一些語法, 為未來新版本的Javascript做好鋪墊。比如一些保留字如: class, enum, export, extends, import, super不能做變數名

2、開啟嚴格模式

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

(1)為腳本開啟嚴格模式

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

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

(2)為函數開啟嚴格模式

要給個函數開啟嚴格模式,需要把”use strict”(或’use strict’;)聲明放在函數體所有語句之前

//將 "use strict" 放在函數體的第一行,則整個函數以 "嚴格模式" 運行

function fn(){
  "use strict";
  return "這是嚴格模式。";
}

3、嚴格模式中的變化

(1)變數規定

①在正常模式中。如果一個變數沒有聲明就賦值。默認是全局變數。嚴格模式禁止這種用法,變數都必須先用var命令聲明,然後再使用。

②嚴禁刪除已經聲明變數。例如,delete x;語法是錯誤的。

(2)嚴格模式下的 this 指向問題

①以前在全局作用域函數中的this指向window對象。
②嚴格模式下全局作用域中函數中的this是undefined。
③以前構造函數時不加new也可以調用,當普通函數,this 指向全局對象
④嚴格模式下,如果構造函數不加new調用,this指向的是undefined如果給他賦值則會報錯
⑤new 實例化的構造函數指向創建的對象實例。
⑥定時器this還是指向window。
⑦事件、對象還是指向調用者。

(3)函數變化

①函數不能有重名的參數。
②函數必須聲明在項層新版本的JavaScript會引入「塊級作用域」( ES6中已引入)。為了與新版本接軌,不允許在非函數的程式碼塊內聲明函數。

四、高階函數

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

<script>
function fn(callback){
  callback&&callback();
}
fn(function(){alert('hi')}
</script>
<script>
function fn(){
    return function() {}
}
 fn();
</script>

此時,fn 就是一個高階函數。函數也是一種數據類型,同樣也可作為參數,傳遞給另外一個參數使用。最典型的就是回調函數

同理,函數也可以作為返回值傳遞進來。

五、閉包

1、變數作用域

變數可以根據作用域的不同可以分為兩種:全局變數 和 局部變數

(1)函數內部可以使用全局變數

(2)函數外部不可以使用局部變數

(3)當函數執行完畢後,本作用域內的局部變數會銷毀

2、什麼是閉包

閉包(closure)指有權訪問另一個函數作用域中變數的函數。簡單理解就是,一個作用域可以訪問另一個函數內部的局部變數

<script>
 function fn1(){    // fn1 就是閉包函數
    var num = 10;
    function fn2(){
      console.log(num); // 10
    }
       fn2()
 }
  fn1();
</script>

3、在 chrome 中調試閉包

(1)打開瀏覽器,按F12鍵啟動chrome調試工具
(2)設置斷點
(3)找到Scope選項(Scope作用域的意思)
(4)重新刷新頁面,會進入斷點調試,Scope 裡面會有兩個參數(global全局作用域、local局部作用域)
(5)當協行到f2()時, Scope面多個Closure參數,這就表明產生了閉包。

4、閉包的作用

延伸變數的作用範圍

六、正則表達式

1、什麼是正則表達式

正則表達式是用來匹配字元串中字元組合的模式。在JavaScript中,正則表達式也是對象。

2、正則表達式在JavaScript中的使用

2.1 創建正則表達式

(1)通過調用 RegExp 對象的構造函數創建

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

(2)通過字面量創建

var 變數名 = /表達式/;

2.2 測試正則表達式 test

test()正則對象方法,用於檢測字元串是否符合該規則,該對象會返回 true 或 false,其參數是測試字元串。

regexObj.test(str)
//regexObj 是寫的正則表達式
//str 我們要測試的文本
//就是檢測str文本是否符合我們寫的正則表達式規範

3、正則表達式中的替換

3.1 replace 替換

replace()方法可以實現替換字元串操作,用來替換的參數可以是一個字元串或者一個正則表達式

stringObject.replace(regexp/substr,replacement)
//第一個參數:   被替換的字元串 或者  正則表達式
//第二個參數:   替換為的字元串
//返回值是一個替換完畢的新字元串

3.2 正則表達式參數

/表達式/[switch]

switch(也稱為修飾符)按照什麼樣的模式來匹配,有三種值:
g : 全局匹配
i :忽略大小寫
gi :全局匹配+忽略大小寫