JavaScript基礎知識


前言

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

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

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

  https://www.w3cschool.cn/javascript/javascript-skillmap.html  這里放上一個學習路線圖,非常詳細非常精彩。當然我的筆記不可能做的十分的全面,所以可以配合看這張學習路線圖與筆記,這個路線圖好像有很多新版特性都沒介紹到,不過在我的筆記中會有相應的介紹。

查看源圖像

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

理論知識

語言介紹

  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瀏覽器作為你的開發工具。

image-20200725004121425

引入方式

嵌入式

  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>標簽中的。

image-20200724212027898

<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的生產版源碼。

image-20200724214109570

變量聲明

  變量就是存儲着一個允許變的值。

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

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

  那么在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>

image-20200724220024928

聲明賦值

  早期的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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM