1. 程式人生 > 實用技巧 >JavaScript基礎知識

JavaScript基礎知識

JavaScript基礎知識

前言

  其實我個人認為JavaScript是一種非常隨便的語言,也是一門很神奇很強大的語言。

  因為之前使用過一段時間的JavaScript並做了些學習筆記都是放在word上的顯得十分雜亂,所以這次也是打算認認真真的重新填一下坑並且認真整理一下JavaScript筆記到部落格園。

  以前在群裡聊JavaScript的時候會經常出現一張圖,我認為這個很有意思,所以就放在這裡做一個填坑目標吧。

  我還是希望將整個的筆記好好整理一下,並且以一種文件格式進行書寫,也方便後期查閱。

理論知識

語言介紹


  JavaScript官方名稱是 ECMAScript

是一種屬於網路的指令碼語言,已經被廣泛用於Web應用開發,常用來為網頁新增各式各樣的動態功能,為使用者提供更流暢美觀的瀏覽效果。

  1995年2月Netscape的布蘭登.艾奇開發了針對網景公司的 Netscape Navigator瀏覽器的指令碼語言LiveScript。之後Netscape與Sun公司聯盟後LiveScript更名為JavaScript

  微軟在JavaScript釋出後為了搶佔市場推出了JavaScript。為了讓指令碼語言規範不在混亂,根據JavaScript 1.1版本推出了ECMA-262的指令碼語言標準。

  ECMA是歐洲計算機制造商協會由Sum、微軟、NetScape公司的程式設計師組成。

  文件中會經常使用 JS 簡寫來代替 JavaScript

  Ps:其實整個JavaScript最早的開發週期只用了兩週,所以在未來很長一段時間裡JavaScript的語法非常混亂,但是隨著時間的更迭慢慢的越來越完善起來。

適用場景


  • 瀏覽器網頁端開發

  • 做為伺服器後臺語言使用Node.js

  • 移動端手機APP開發,如Facebook的 React NativeuniappPhoneGapIONIC

  • 跨平臺的桌面應用程式,如使用 electronjs

  所以JS是一專多能的語言,非常適合學習使用。

發展歷史


  • 1994年Netscape(網景)公司釋出了 Navigator

    瀏覽器1.0版本,市場佔用率超過90%

  • 1995年釋出了JavaScript 語言

  • 1996年 JS在 Navigator瀏覽器中使用

  • 1996年微軟釋出JScript在IE3.0中使用

  • 1996年11月網景公司將JS提交給ECMA(國際標準化組織)成為國際標準,用於對抗微軟。

    由ECMA的第39號技術專家委員會(Technical Committee 39,簡稱TC39)負責制訂ECMAScript標準,成員包括Microsoft、Mozilla、Google等大公司。

  • 1997年 ECMA釋出ECMA-262標準,推出瀏覽器標準語言 ECMAScript 1.0

    ECMAScript 是標準而Javascript是實現

  • ...

  • 2009年ECMAScript 5.0釋出

  • 2011年ECMAScript5.1釋出,成為ISO國際標準,從而推動所有瀏覽器都支援

  • ...

  • 2015年ECMAScript6釋出,更名為ECMAScript 2015。

  • 2016年ECMAScript7釋出,ECMAScript2016

  • 2017年ECMAScript8釋出,ECMAScript2017

  • 2018年ECMAScript9釋出,ECMAScript2018

  • 2019年ECMAScript10,ECMAScript2019

  • 2020年ECMAScript11,ECMAScript2020

  • ....

  從2015年開始 tc39委員會決定每年釋出新的ECMAScript版本

chrome使用


  在學習Js的過程中,推薦使用chrome瀏覽器作為你的開發工具。

引入方式

嵌入式


  HTML文件中使用<script>標籤,在<script>標籤中嵌入Js程式碼即可,關於type什麼的文件型別宣告可寫可不寫。

  使用這種在方式最好是將Js程式碼寫在尾部。也就是寫在HTMLCSS程式碼之後。

  這種做法是因為如果我們的Js程式碼需要去查詢某一標籤而將其放在頭部的話HTML的程式碼可能還沒有加載出來,會出現一些不穩定的特殊情況。

  我個人是非常喜歡夾在<body>標籤後的...

<!DOCTYPE html>
<html lang="en"><head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
</head><body></body>
    <script>
        console.log("hello,world");  // hello,world
    </script>
</html>

引入式


  同樣的,也是使用<script>標籤,併為其src屬性指定好Js檔案路徑即可,關於type什麼的文件型別宣告可寫可不寫。

  還是推薦將它放在尾部,但是也有很多是放在<head>標籤中的。

<script src="./first_js.js" type="application/x-javascript"></script>

程式碼註釋

  Js中的註釋有兩種,一種單行註釋,一種多行註釋。

單行註釋


  使用//放在語句前,即可完成單行註釋。

<script>
        // 下面是個自執行函式
       
        (function (){
                console.log("hello,world");
        })()
</script>

多行註釋


  使用/*開頭,*/結束,可包含多行。

<script>
        /* 下面是個自執行函式
        它沒有引數 */
        
        (function (){
                console.log("hello,world");
        })()
</script>

自動分號

自動分號


  在一段語句結束後,應當加上;號,但是這並不是強制性的而是一種規範。

<script>
​
        (function (){
                console.log("hello,world");
                alert("hello,world");
                document.write("hello,world");
        })();
​
</script>

意義作用


  儘管你可以不加,但是請注意前端的程式碼一般來說在上線部署後都會進行壓縮。

  在使用構建工具時,不使用分號結束可能會造成異常!

  我們可以看一下一個非常常見的JsjQuery的生產版原始碼。

變數宣告

  變數就是儲存著一個允許變的值。

  如年齡,愛好,居住地等都可以定義為變數。

  變數的使用都是先聲明後使用,這個應該是非常基礎的,在每個語言中都是這樣。

  那麼在JavaScript中關於變數宣告有很多有意思的點,可以慢慢往下看。

命名規則


  Js中的變數是弱型別可以儲存所有型別的資料,即變數沒有型別而值有型別。變數名以字母$_開始,後跟字母數字_

  Js中的語言關鍵字不能用來做變數名,比如 true、if、while、class 等。

  請不要輕易使用用$來作為變數名的起始,因為它被jQuery給霸佔了,目前請謹記這一點。

  正確的命名規範

<script>
​
        var username = "Yunya";
        var _age = 18;
        var $select = "Please do not use $ to start variable names lightly, although it is not wrong";
        
</script>

  錯誤的命名規範

<script>
​
        var 9username = "ERROR";
        var (age = "ERROR";
        var --select = "ERROR";
        
</script>

宣告賦值


  早期的Js使用者都同一用var來宣告變數,但是es6後推出了let,具體的作用我們這裡先不管。先看一下最基本的使用,由於Js是一門弱型別語言,所以不用強調變數宣告的型別。

  先宣告並賦值,後使用

<script>
        
        // 先宣告並且賦值
        var username = "YunYa";
        let age = 18;
        // 後使用
        console.log(username);  // YunYa
        console.log(age);  // 18
​
</script>

  上面是最常用的方式,其實也可以先宣告,再賦值,後使用。

<script>

        // 先宣告
        var username;
        let age;
        // 再賦值
        username = "YunYa";
        age = 18;
        // 後使用
        console.log(username);  // YunYa
        console.log(age);  // 18

</script>

  我們還可以一次性宣告賦值多個變數。

<script>

        var username = "YunYa", age = 18, gender = "male";
        console.log(username);  // YunYa
        console.log(age);  // 18
        console.log(gender);  // male

</script>

  也可以進行鏈式賦值

<script>

        var a=b=c=1;
        console.log(a);  // 1
        console.log(b);  // 1
        console.log(c);  // 1

</script>

弱型別


  弱型別其實就是說存的是什麼型別的值,就是什麼型別的變數。

  不用提前宣告變數變數再進行儲存。

<script>

        var username = "YunYa";
        var age = 18;
        var other = {"hobby":"basketball","marriage":false,"height":192,"weight":126,};

        // typeof 是檢視變數的型別方法
        console.log(typeof username);  // string
        console.log(typeof age);  // number
        console.log(typeof other);  // object

</script>

常量宣告

  常量儲存一些不允許被改變的值。

  PI,性別,籍貫等等都可以定義為常量。

命名規則


  常量的命名規則和變數基本一致,但是一定要注意!常量的命名規則是全部大寫形式,這是一種規範。

  常量名建議全部大寫

  只能宣告一次變數

  宣告時必須同時賦值

  不允許再次全新賦值

  可以修改引用型別變數的值

  擁有塊、函式、全域性作用域

<script>
        // 常量宣告全用大寫
        const PI = 3.1415926535897;
        console.log(PI);  // 3.1415926535897

</script>

宣告賦值


  常量我們一般都會使用const來進行宣告並賦值,它有一個特點,即宣告之後不允許改變。

<script>
        
        // 常量宣告全用大寫
        const PI = 3.1415926535897;
        PI = 100;
        console.log(PI); 
        // Uncaught TypeError: Assignment to constant variable.
        // 型別錯誤: 將值分配給了一個不變的變數(常量)

</script>

var let const 區別

意義作用


  不使用他們會全部亂套,因為有不同的作用域存在,如果不使用他們則代表將所有的變數全部放進全域性作用域中。

  程式碼及易出現問題!

<script>

        username = "YunYa";
 
        function test(params) {

                console.log(username); // YunYa
                username = "Jack";   
                console.log(username); // Jack
        };
        test();

        // 可以看到,被汙染了..
        console.log(username); // Jack

</script>

<script>

        var username = "YunYa";
 
        function test(params) {

                console.log(username); // undefined 這是因為自身區域性作用域有一個 username,但是此時還未定義。所以不去找全域性的name了,只好顯示undefined。
                var username = "Jack";   
                console.log(username); // Jack
        };
        test();

        // 可以看到,未汙染了..
        console.log(username); // YunYa

</script>

變數提升


  變數提升其實你可以將它當做是預載入,它會預先來檢查所有宣告的變數名字是否合法。

<script>

        console.log("執行我了...");  // 沒執行
        let for = "YunYa";  //  Uncaught SyntaxError: Unexpected token 'for'
        console.log("執行我了...");  // 沒執行
        
</script>

  很明顯的看到,程式碼都沒執行,但是卻丟擲異常。這是預載入做的第一步事情,檢查名稱是否合法。

  當預載入第一步執行完畢後,開始做第二步事情,對var宣告的變數進行開闢記憶體空間(注意:是開闢記憶體空間,並未賦值,並且letconst宣告的變數都不會開闢記憶體空間)。

  也就是說,當Js程式碼開始執行時,檢查完變數名是否合法後,它會預先拿到所有var宣告的變數名的名字(函式名也會),但並不會進行賦值。

  只有當真正開始執行程式碼並且走到賦值程式碼時才會進行賦值操作,所以你可以看到下面的這種情況。

<script>

        // 為什麼沒丟擲異常?
        console.log(username)  // undefined
        var username = "YunYa";
        
</script>

  如果使用一個未被定義的函式,那麼才是真正的會丟擲異常。

<script>

        console.log(age)  // Uncaught ReferenceError: age is not defined
        var username = "YunYa";   
  
</script>

TDZ暫時性死區


  TDZ又稱暫時性死區,指變數在作用域內已經存在,但必須在let/const聲明後才可以使用。

  TDZ可以讓程式保持先聲明後使用的習慣,讓程式更穩定。

  變數要先聲明後使用

  建議使用let/const而少使用var

  使用let/const 宣告的變數在宣告前存在臨時性死區(TDZ)使用會發生錯誤。

  其實說白了就是letconst來宣告的變數必須遵守先聲明後使用的原則。

<script>
        
        // 意思就說,不能在完成之前訪問name這個變數
        console.log(username)  // Uncaught ReferenceError: Cannot access 'name' before initialization
        let username = "YunYa";   
  
</script>

<script>

        // 意思就說,不能在完成之前訪問name這個變數
        console.log(username)  // Uncaught ReferenceError: Cannot access 'username' before initialization
        const username = "YunYa";   
  
</script>

塊作用域


  作用域你可以簡單的理解為,只要有{}括起來的地方全是作用域,它的作用就是讓相同名字的變數名之間互不衝突。

作用域
全域性作用域 變數名全域性有效。
區域性作用域 隸屬於全域性作用域之下,變數名在函式,類中有效,可訪問全域性作用域中的變數。
塊作用域 隸屬於全域性作用域之下,對於var來說不存在,對於let來說則存在,常見for迴圈,通俗講只要有不是區域性作用域和全域性作用域而被{}包裹的程式碼塊全部稱為塊作用域。

  注意:letconst都具有塊作用域,而var則不具有。

  下面例子使用var則會造成汙染(會當成全域性作用域來看待,不具有塊作用域),而使用let則不會(const不可多次賦值應用)。

<script>

        var i = 100;
        for(var i = 0;i < 5;i++){
                console.log(i);  // 0 1 2 3 4 
        }

        // 此時我們在想用 100 的那個 i 抱歉,被替換了。

        console.log(i);  // 5
  
</script>

<script>

        let i = 100;
        for(let i = 0;i < 5;i++){
                console.log(i);  // 0 1 2 3 4 
        }

        // 未替換。

        console.log(i);  // 100
  
</script>

重複定義


  在同一作用域下,使用var定義的變數名可重複定義,而letconst則不可重複定義。

  var

<script>

        var num = 100;
        var num = 1000;

        // 明顯不太好

        console.log(num);   // 1000
  
</script>

  let

<script>
        
        // Uncaught SyntaxError: Identifier 'num' has already been declared
        // 語法錯誤 num 已經被定義
        let num = 100;
        let num = 1000;

        console.log(num); 
  
</script>

  const

<script>

        // Uncaught SyntaxError: Identifier 'num' has already been declared
        // 語法錯誤 num 已經被定義
        const num = 100;
        const num = 1000;

        console.log(num);   // 1000
  
</script>

windows物件


  使用var定義的變數會被存入windows物件,而letconst卻不會。

  var

<script>

        var username = "YunYa";
        console.log(window["username"]);  // YunYa
  
</script>

  let

<script>

        let username = "YunYa";
        console.log(window["username"]);  // undefined
  
</script>

  const

<script>

        const username = "YunYa";
        console.log(window["username"]);  // undefined
  
</script>

差異總結


var let const區別
var let const
變數提升
TDZ暫時性死區
塊作用域
同一作用域下重複定義 允許 不允許 不允許
windows物件 新增 不新增 不新增
總結:儘量少使用var多使用let

嚴格模式

  嚴格模式可以讓我們及早發現錯誤,使程式碼更安全規範,推薦在程式碼中一直保持嚴格模式執行。

  只需要在書寫程式碼前加上"use strict";即可。

  主流框架都採用嚴格模式,嚴格模式也是未來JS標準,所以建議程式碼使用嚴格模式開發

基本差異


  變數必須使用關鍵詞宣告,未宣告的變數不允許賦值。

<script>

        //  Uncaught ReferenceError: username is not defined

        "use strict";
        
        username = "YunYa";  

        console.log(username);

</script>

  關鍵詞不允許做變數使用

<script>

        //  Uncaught SyntaxError: Unexpected token 'try'

        "use strict";
        
        var try = "YunYa";  

        console.log(username);

</script>

  變數引數不允許重複定義

<script>

        //  Uncaught SyntaxError: Duplicate parameter name not allowed in this context

        "use strict";
        
        function test(x,x){
                console.log("執行了...");
        };

        test();

</script>

  單獨為函式設定嚴格模式

<script>
        
        function test(){
                "use strict";
                console.log("執行了...");  // 執行了...
        };

        test();

</script>

  為了在多檔案合併時,防止全域性設定嚴格模式對其他沒使用嚴格模式檔案的影響,將指令碼放在一個執行函式中。

<script>
        
        (function (param) {

                "use strict";
                let url = "www.google.com";
                console.log(url);
                
          })();

</script>

解構差異


  非嚴格模式可以不使用宣告指令,嚴格模式下必須使用宣告。所以建議使用 let等宣告。

<script>

        // "use strict"; 
        // 在嚴格模式下不允許這樣使用

        ({ name, other } = { "name":"YunYa-cnblogs","other":"good" });
        console.log(name, other); // YunYa-cnblogs good


</script>