JavaScript入門①-基礎知識築基

安木夕發表於2022-11-30

image.png

01、JavaScript基礎知識

JavaScript(縮寫:JS)是一種具有物件導向能力的、解釋型的程式語言,基於物件和事件驅動,具有相對安全性的客戶端指令碼語言。JavaScript是一門完備的 動態程式語言,當應用於 HTML 文件時,可為網站提供動態互動特性,是前端開發最主要、正式的程式語言。

image

ECMAScript 是由 ECMA 國際標準化組織 制定的一套指令碼語言的標準化規範,JavaScript算是他的實現,作為基礎語法規範,構成了JavaScript的核心。再加收瀏覽器提供的DOM(HTML網頁內容)操作API、瀏覽器BOM操作API,共同組成了 JavaScript。

1.1、語法規範

JS程式碼以行為單位,(半形)分號;結尾。

?註釋//

  • 單行註釋//開頭。
  • 多行註釋/*多行註釋 */(同css)

?程式碼風格

  • 區分大小寫,字母、數字、下劃線組成,不能數字開頭,不能是關鍵字。
  • 小駝峰命名(推薦):initialColor

?關鍵字: 內建的關鍵詞:如var、do、else、enum、eval、false、for、if、void、function、switch...

?語句塊:花括號 { 程式碼塊 }

1.2、引用方式

  • 行內JS:元素標籤內部的JS程式碼。
  • 內部JS:定義在<script>標籤裡的JS程式碼,可以放到head中、body中、body後,推薦body後,先載入html再執行JS。
  • 外部JS(推薦):單獨的JS檔案,透過script標籤引入,src屬性指定JS檔案地址,此時標籤中寫的程式碼就無效了。
  • 動態載入:透過DOM的API動態載入JS指令碼資源,用JS建立<script>標籤並引入資源。
<script>屬性 描述 值/備註
src 外部資源地址,與嵌入指令碼程式碼不可同時使用 <script src="js1.js" async></script>
type 定義指令碼語言型別,可空,預設為JavaScript型別 支援的MIME型別包括text/javascript、 text/ecmascript、 application/javascript 和application/ecmascript
async 非同步並行載入,只針對外部JS資源 多個async指令碼載入完成的順序不確定
defer 等HTML解析完成再執行JS,在DOMContentLoaded之前執行,只針對外部JS資源 多個指令碼資源順序載入

?指令碼載入策略

  • 如果指令碼無需等待頁面解析,且無依賴獨立執行,那麼應使用 async
  • 如果指令碼需要等待頁面解析,且依賴於其它指令碼,應使用 defer,將關聯的指令碼按所需順序置於 HTML 中。
<body>
    <div>
        <h1>基礎語法</h1>
        <input type="button" value="行內JS" onclick="alert('Hello world!');"/>
        <input type="button" value="外部JS呼叫" onclick="hello();"/>
    </div><hr/>
</body>
<script>
    console.log("內部js:網頁載入完成!");
</script>
<!-- 引入外部js檔案,設定了src屬性,script內部的程式碼就無效了 -->
<script src="../tstudy/js/js1.js" type="text/javascript" async></script>

02、變數申明var/let/const

變數,就是一個用於存放數值的容器,比如年齡=20,“年齡”就是變數,“20”是他的樹值。JS是一種弱型別語言,不需要指明資料型別,用varlet關鍵字申明即可。

?申明方式

  • 申明並賦值,1步完成:var str="hello world";
  • 先申明,再賦值,2步完成。var str1; str1="hello world"; // 預設值為undefined

?動態資料型別:JavaScript 是一種“動態型別語言”,意味著一個變數可以被賦值為各種型別資料值,透過typeof判斷資料型別。

let age;
console.log(age); //undefined
age =20;
console.log(typeof age); //number
age='年芳二十';
console.log(typeof age); //string
var let (IE11 ES6) const (IE11 ES6)
說明 變數申明 變數申明 只讀常量申明:申明時必須初始化值,不可更改
作用域 全域性(整個文件)或整個函式體 塊級作用域{}包含的區域 塊級作用域{}
命名規範 推薦:小駝峰命名 同var 推薦:全大寫+下劃線,const MAX_SPEED
預設值 undefined undefined 必須賦值
變數提升 提升所有var申明的變數,可以先使用後申明(不推薦),把var變數申明提升到程式碼頭部,⚠️注意不包括賦值 不會提升,順序執行:必須先申明,後使用。存在暫時性死區
let foo=(foo+55)第二個foo未申明報錯
不會提升,順序執行:必須先申明,後使用。
全域性屬性 在全域性環境時,會成為頂級物件的屬性(不可配置屬性),作為全域性變數存在。
var age=3; //this.age;window.age
重複申明 可以重複申明,覆蓋前面的,有點太隨意了 不可重複申明,作用域內重複申明會報錯
● 包括var、const申明的變數
● 子塊可重新申明let,不同的作用域了
● 子塊中用var變數會重複,var會提升
不可重複申明,會提示錯誤,同let
申明多個 支援:var s1=1,st=2; 支援:let s1,s2=2; 支援:const s1=1,s2=2;
效能 一般 一般 編譯器會做常量替換最佳化,提升程式碼效率
總結 ?有點粗獷,不推薦 ?更嚴謹,推薦使用 ?不僅更嚴謹,效能還好,優先推薦!!!

暫時性死區:由於沒有了變數提升,及塊級作用域,let、const變數只能在申明後才能用,在這之前不可用,稱為“暫時性死區”。

2.1、作用域

特別注意的是 var 作用域在整個文件或函式內,整個文件也可認為是一個特殊的頂級函式。

  • 如下經典的for迴圈示例,var的變數提升導致輸出結果詭異。
for (var i = 1; i <= 5; i++) {
    setTimeout(function () {  //setTimeout為非同步執行函式
        console.log(i);	//輸出6 6 6 6 6
    }, 0);
}
//換成let,則輸出:1 2 3 4 5
//換成const,輸出1,然後報錯 Assignment to constant variable
  • var作用域在整個函式
function foo() {
    var x = 1; //x作用域在foo函式體內,包括巢狀函式bar也可以訪問
    function bar() {
        var y = 2;	//y作用域只在函式體bar
        console.log(x); // 1 
        console.log(y); // 2 
    }
    bar();
    console.log(x); // 1 (`x` 在作用域內)
    console.log(y); // Uncaught ReferenceError: y is not defined
}
foo();
console.log(x); // Uncaught ReferenceError: x is not defined
console.log(y);    // Uncaught ReferenceError: y is not defined
  • let作用域僅限{}塊,可以是函式的塊function{}、迴圈的塊for{},或者就一個孤獨的塊{}
let s1;
let s1;  //Uncaught SyntaxError: Identifier 's1' has already been declared
let x = 1; //後面塊內的 var x會被變數提升,導致重複變數定義報錯
{	
    var x = 2; //Uncaught SyntaxError: Identifier 'x' has already been declared
}

2.2、變數提升

變數提升:JS引擎是先解析程式碼,獲取所有被var申明的變數,然後再逐行執行。只提升用var顯示申明的變數,會把所有var的申明提升到全域性程式碼的頂部先執行,⚠️注意只提升申明,不包括賦值。

console.log(sname);  //undefined  只提升了x的變數申明,值為預設值
var sname = "sam";
var x=1;
function print() {
    console.log(sname);  // sam
    console.log(window.sname);  //sam 全域性文件中申明的var變數,會作為 window 的全域性變數屬性
    console.log(this.sname);  //sam 這裡的this 指向 全域性物件window
}
print();

?隱式全域性變數:無申明變數(str="hello";),自動提升為隱式全域性變數(不論在什麼地方),類似var變數,除了沒有變數提升。so,?儘量不要這麼使用,在嚴格模式下('use strict';)這樣寫是會報錯的。

x = 0;  //未申明變數,成為隱式全域性變數
function f() {
    y = 1;  //當執行該函式時,未申明變數,成為隱式全域性變數
    var z = 2;  //z是函式內部申明的變數,作用域只在函式體內
}
f();
console.log(x, y); // 0 1
console.log(window.x, window.y); // 0 1
console.log(z);  //Uncaught ReferenceError: z is not defined

2.3、解構賦值

解構賦值是ES6新增的語法,可以一次性給多個變數賦值,提高了程式設計效率,賦值操作更簡潔。具體方式就是:將屬性/值從物件/陣列中取出,賦值給其他變數的一種賦值方式。有兩種解構賦值的語法形式:

  • 陣列解構:類似陣列的寫法,從陣列中按順序賦值,這裡陣列可以是其他可迭代資料。
  • 物件解構:類似物件的寫法,從物件中按屬性名賦值。
//變數一個個賦值
let x1 = 1, x2 = 2, x3 = 3, x4 = 4;
// 用陣列解構賦值
let [y1, y2, y3, y4] = [1, 2, 3, 4];

[x1, x2] = [x2, x1];	//用來交換x1、x2的值,不用第三方變數
// 從物件解構賦值
let { c, d } = { a: 0, c: 1, d: 2 };

03、基礎資料型別

ECMAScript 有 6 種基本型別UndefinedNullBooleanNumberStringSymbol(符號),其他就是都是Object物件型別了,如ArrayobjectMapDatefunction等。

資料型別 描述
Number 數值:整數、小數(浮點型)
● 都是64位浮點型別儲存的,最高精度17位,所以1和1.0是相等的。
● 浮點數計算時(小數位)可能不準確,不建議用浮點數做判斷。
● 儲存時會自動轉換整數的浮點數值,如1.0轉換為1。
let myAge = 17;
Boolean 布林型別:有兩個值truefalse let isFirstBlood=true;
null 空值關鍵字,表示空缺、空值,其型別為object,表示一個空物件的指標。undefined繼承自null,等值比較時返回true。 注意判斷object型別時須排除null。
Undefined 未定義:只有一個值undefined,表示未定義或不存在
● 未賦值的變數預設為undefined
● 呼叫函式時未傳遞必須引數,則為undefined
● 函式沒有返回值,預設返回undefined
String 字串:單引號、雙引號括起來,用加號+連線字串。
不可變:JS的字串一旦建立不可變,所有更改都會建立新的字串
● 每一個字元元素是16 位的無符號整數值

Symbol ES6 符號型別,具有唯一性不變性,常用於物件屬性名 const fooSym = Symbol('foo')
bigint 新新增的資料型別(ES2020)
object物件 物件:引用型別,各種值的組合
 Array 陣列物件 var list1=[1,2,3];
 JSON物件 物件:var jobj={name:"zhang",age:1};
 function 函式,本身也是物件 function f1(){/*...*/}

⚠️注意不要將基本型別中的布林值 true / false 與值為 true/false 的 Boolean 物件弄混了,基本型別Boolean是一個物件。

console.log(typeof 1); //number
console.log(typeof true); //boolean
console.log(typeof null); //object
console.log(typeof undefined); //undefined
console.log(typeof 'abc'); //string
console.log(null == undefined); //true 值比較
console.log(null === undefined); //false  恆等比較
//boolean
const x = new Boolean(false);  //new Boolean()建立了基本型別Boolean的物件,就不是一個平平無奇的值型別了。
console.log(typeof x);  //object
console.log(x.valueOf()); //false valueOf()方法獲取物件的基本資料的值
console.log(Boolean(undefined));     //false
console.log(Boolean(null));     //false
console.log(Boolean(NaN));     //false
console.log(Boolean(0));     //false
console.log(Boolean(""));     //false
console.log(Boolean(1));     //true
console.log(Boolean(-100));     //true
console.log(Boolean("abc"));     //true

3.1、Number數字

Number的屬性、方法:

屬性/方法 描述 示例
?靜態屬性/方法
Number.NaN NaN是一個特殊的Number值,即非數值(Not a Number)
NaN和任何值都不相等,包括它自己,和任何值計算都為NaN
MathparseInt函式執行失敗會返回NaN
window.NaN
Number.MAX_VALUE 最大數值(靜態屬性),值接近於 1.79E+308
Number.MIN_VALUE 最接近 0 的正值,而不是最小的負值,約為 5E-324
Number.isNaN() IE? 判斷是否等於NaN,window.isNaN是判斷是否非數值,坑! 只有NaN才返回true
Number.isInteger() IE? 是否為整數
Number.parseFloat() IE? 解析浮點數,從第一個非空字元解析獲取數字,識別第一個小數點 window.parseFloat()
Number.parseInt() IE? 解析整數,從第一個非空字元解析獲取數字,支援進位制引數 window.parseInt()
?建構函式
Number() 轉換為數字(忽略空格)。Number()轉換資料不同於parseint、parseFloat,要求必須為合法數字,要求更嚴格,不成功便成仁。 Number(true) //1
?例項屬性/方法
toFixed(小數位數) 轉換為指定小數位數的字元,多了會四捨五入,不足用0補位 n1.toFixed(2)
toString() 轉字串,引數可以指定基數(進位制) n2.toString(2) //2進位制

?注意浮點數的精度0.1+0.2 //輸出 0.3000000000000000**4** 。由於浮點數的精度問題,永遠不要用浮點數值去做條件判斷。這種錯誤是由於IEEE 754標準導致的。

Number.parseFloat("123.4a5"); //123.4
Number.parseInt("123.4a5"); //123
//注意,兩個方法是不同的,全域性的window.isNaN()是判斷是否非數值。
window.isNaN("a") //true
Number.isNaN("a") //false  //這屬於JS坑爹的設計,兩個含義完全不同

console.log(Number(""));        //0
console.log(Number("123abc"));     //NaN,不同於parseint、parseFloat
console.log(Number("12.12.12"));     //NaN,不同於parseint、parseFloat
console.log(Number.parseFloat("12.12.12"));     //12.12

let n1=1.336,n2=100;
n1.toFixed(2)	//1.34
n2.toFixed(2)	//100.00

window.parseFloat(string):從字串的第一位(空字元會被忽略)開始,如果是數字(正號+、負號-、數字0-9、第一個小數點.、科學計數法e/E)則轉數字,直到非數字或結束。

console.log(parseFloat("123abc"));    //123
console.log(parseFloat("abc123"));    //NaN
console.log(parseFloat("11.11"));      //11.11
console.log(parseFloat("11.11.33"));   //11.11

window.parseint(string):同parseFloat,除了不識別小數點。

console.log(parseInt("123abc"));    //123
console.log(parseInt("abc123"));    //NaN
console.log(parseInt("11.11"));      //11

3.2、String字串

String:字串物件,提供各種字串操作。

屬性/方法 描述 示例
?建構函式
String() 支援任意值轉換為字串,包括nullundefined,都是直接加引號,很粗暴!?可以用來判斷null、undefined String(null) //"null"
?例項屬性/方法
length 字串長度 "abc".length; // 3
charAt(index) 返回指定位置的字元
indexOf(char) 返回字元的索引位置,從前往後找,lastIndexOf是從後往前找 s1.indexOf("12")
substr(start,length?) 擷取字串:指定起始位置長度,無length到結尾(下同) s1.substr(2)
substring(start,end?) 擷取字串:指定起始位置結束位置
slice(start,end?) 擷取字串:起始位置結束位置,同substring,區別是支援負數(倒數),(slice /slaɪs/ 切片) str.slice(0,-1);//擷取0到倒數第二位置的字元
split(separator,limit?) 按照分隔符分割字串為陣列 (split /splɪt/ 分裂)
trim() 移除首尾的空白字元,返回新字元,不會改變原有字元。
trimStart() 同上,值移除開頭的空白字元,還有移除末尾的trimEnd()
padStart(len,str) 從頭補齊字元長度到len,str為去替補的字元,沒有則空格 "12".padStart(5,'0')
padEnd(len,str) 補齊字元長度,從尾部開始
replace(old, new) 字元替換,str.replace("臺灣","臺灣省"),支援正則和函式
repeat(n) 建立一個重複n次的新字串 "12".repeat(2) //1212
toLowerCase() 字元轉小寫,大寫是toUpperCase()
includes(str) 判斷是否包含指定的字串
startsWith(str) 判斷是否以指定字元開頭,endsWith()判斷結尾
search(str) 字元搜尋或正則匹配搜尋
match(regexp) 正則匹配搜尋字元

?字串的不變性:字串一經建立不會改變。 let str="abc"; str="123";

  • 這裡的不改變,不是字元變數str不能修改,是指字串"abc"本身不可更改,修改str會建立新的字元。所以,字元的操作都不會影響原來的字串值,而是建立新的字串。
  • 字元連線建立新字元:字元的連線,如+,會建立新的字串。

?模板字串(IE?):${var}+反引號 `` 包裝

板字串可以包含特定語法(${expression})的佔位符,由一個內建函式負責計算表示式並輸出最終的字串。

let x=1,y=2;
console.log(`sum: ${x} + ${y} = ${x+y}`); //sum: 1 + 2 = 3

?JavaScript 特殊/跳脫字元:在字串中使用的特殊符號

字元 描述
\0 Null 位元組
\b 退格符
\f 換頁符
\n 換行符
\r 回車符
\t Tab (製表符)
\v 垂直製表符
\' 單引號
\" 雙引號
\\ 反斜槓字元(\)

3.3、型別( 隱式 )轉換

隱式型別轉轉換,是自動進行的,也叫自動型別轉換。

字串 數字 布林值
undefined "undefined" NaN false
null "null" 0 false
true "true" 1 true
false "false" 0 false
""(空字元) "" 0 false
"1.5" "1.5" 1.5 true
"one" "one" NaN true
0 "0" 0 false
-1 "-1" -1 true(非0數字都true)
1 "1" 1 true
NaN "NaN" NaN false
[](空陣列)
0 true
[5]一個數字
裡面的數字5 true
["a"][1,2]其他陣列 NaN true
{...}物件 NaN true

?隱式轉換總結

  • 轉boolean:undefined、null、NaN、0、空字元轉bool都為false;非0數字(包括負數)、非空字元(包括”true“、”false“)、物件、空陣列[] 轉boolean都為true
  • 轉數字:非空字串都是數字(忽略空格)的轉對應數字,否則NaN;null、空字元轉數字為0。
  • 轉字串:任意型別轉字串加引號,包括undefined、null。
  • +運算:字串+任意型別(包括空字元)均轉換為字串;boolean、數字轉數值進行相加。
  • -*/% 運算:都是隱式轉換為數值運算。
  • ==、>、< 比較運算子:不同的值型別轉數字;都是字元比較碼值;如果存在物件,先轉換為原始值。
console.log("-1" - 1); // -2
console.log(2 > true); // true
console.log("one" + true); // onetrue
console.log("1.5" * 2); // 3
console.log("1.5" + 2); // 1.52
console.log([5] / 2); // 2.5

?顯示型別轉換就是呼叫各種方法、型別建構函式進行顯示的資料轉換。

  • toString():基本每種資料型別都提供了toString()方法,轉換為字串,除開null和undefined不可使用,會報錯。
  • 型別建構函式:Boolean()、Number()、String()的型別函式,都可以轉換對應資料型別。
  • valueOf():valueOf()方法可以轉換物件為一個基本資料值。
  • 其他如parseInt()、parseFloat()...等方法。

3.4、值型別與引用型別

⁉️堆和棧

  • 棧(stack):提供程式碼執行環境,並存放值型別、變數識別符號。速度快,空間有限(不同瀏覽器不同)。
  • 堆(heap):存放引用型別資料,速度慢,空間大。
值型別(基本型別) 物件/引用型別
資料型別 undefined、null、Boolean、Number、String、Symbol Array、object、window,function等
包裝型別:String、Number、Boolean;
單體內建物件:Global、Math
儲存位置 儲存在棧中(變數識別符號、變數值),佔用空間固定
fbc57ebc6a96470b3b45d154cd09382b_1890110-20200327154803560-2032961964.png
儲存在堆中,佔用空間不固定。變數識別符號儲存在棧區,值為地址指標,指向儲存在堆區的物件資料。
屬性方法 不能新增任何屬性、方法。 可以動態新增屬性和方法
複製 複製變數值 複製地址指標(變數值是物件的指標),指向同一物件
引數傳遞 值傳遞,不影響原有變數 引用地址傳遞,共用同一個物件
垃圾回收 函式執行完就回收了 沒有任何引用時,才會被垃圾回收機制收回
型別驗證 typeoftypeof 0; //number instanceof[] instanceof Array //true
Object.prototype.toString.call({}) //[object Object]
==比較 值型別是值比較 引用型別比較引用地址,所以要用恆等===比較

image


04、運算/運算子

4.1、➕算數運算子

運算子 描述 示例
+
-
*
/
% 取餘數 6%3; //=0
** 指數,冪運算,等同於Math.pow(a,b) 3**2; //=Math.pow(3,2)=9
++ 自加1,符號在前面的先運算,再賦值,在後面的反之 x=++y; //y=1+y; x=y;
x=y++; //x=y;y=1+y;
-- 自減1,同上

?運算子優先順序:[ ++,--,!] > [*,/,% ] > [ +,- ]

var x=1;  //經典面試題
console.log(x+x++ + ++x); //1+1+(1+2)=5

?+加運算子會隱式轉換+運算就是字元相加、數字相加兩種情況

  • boolean、數字相加會隱式轉換為數值進行相加。
  • 字串 + 非字串會隱式轉換為字串。
console.log(true+false);    //1
console.log(true+3);    //4
console.log(true+"1");    //true1
console.log("123"+123);    //123123
console.log("123"+[1,2,3]);    //1231,2,3

?-*/% 隱式轉換數值:都是數學運算轉數字。減、乘、除、取餘運算都是數學運算,會隱式轉換為數字再運算。

console.log("123"-"12");    //111
console.log("123"-12);    //111
console.log("123"-1-true);    //121
console.log("123"/true);    //123
console.log("123"/2);    //61.5

4.2、⏸️賦值運算子

運算子 描述 示例
= 賦值運算子,一個神聖的儀式
+= 加法賦值 x+=y //x=x+y
-= 減法賦值 x-=y //x=x-y
*= 乘法賦值 x*=y //x=x*y
/= 除法賦值 x/=y //x=x/y
%= 取餘賦值 a%=3 //a=a%3

4.3、?比較運算子

運算子 描述 示例/備註
>,<,>=,<= 大於,小於,大於等於,小於等於
== 相等比較,比較變數的值,而不管其型別 "1"==1; //true
=== 恆等比較,比較型別和值 無型別轉換
!= !=不等於比較
!== !==不恆等比較 無型別轉換

比較運算子會隱式轉換為數值

  • 都是字元,轉為碼值進行比較,
  • 兩個不同型別比較,隱式轉為數值,然後進行比較。
  • 引用型別永遠不相等,雖然其內部的資料一模一樣,因為比較的是引用地址。
  • 推薦恆等,由於 ==!= 比較會隱式轉換,會遇到較多奇葩問題,在開發中,我們一般使用嚴格比較恆等 === !==
  • NaN與任何值比較,都是false, Infinity 只等於它自身。console.log(NaN==NaN); //false
  • null 和 undefined, 他們直接相等,和其他原始型別比較,不相等。
console.log("123">"45");    //false 都是字元比較字元碼值
console.log("123">45);  //true  轉換為數值比較
console.log("123"==123);    //轉數值比較,true
console.log(""==false);  //true 轉為數值比較
console.log("false"==false);  //false 轉為數值比較
console.log("true"==true);  //false 轉為數值比較
console.log([1,2,3]==[1,2,3]);  //false,陣列是物件

4.4、❗邏輯運算子

運算子 描述 示例/備註
! !邏輯非運算子 !false //true
&& &&|| 也叫短路運算子:從左往右判斷,符合要求就不繼續執行了
邏輯與&&=同時滿足:返回第一個為false的值,否則最後一個值
1 && 2 && 3 //返回3
1 && 2 && false && 3 //返回false
|| 邏輯或=滿足一個即可:返回第一個為true的值,否則最後一個值 1 || 2 || false //返回1

邏輯運算子會隱式轉換為boolean值。

短路運算子&&||常用來判斷都為真、至少有一個為真:

let user = { name: "sam", score: 98, age: 12 };
if (user.age <= 12 && user.score > 95)
    console.log(`${user.name} 是一個少年天才!`);

4.5、⁉️其他運算子

運算子 描述 示例
?: 三元表示式判斷條件 ?條件為真 :條件為假 age = 4 > 2 ? 4 : 2; //4
??= 邏輯空賦值運算子: (x ??= y) 僅在 x 是(null 或 undefined) 時對其賦值y x??="default";
?. || 可選鏈運算子,不為空(null 或 undefined)時才執行。可以沒有 ||,返回undefined page=res?.data?.size ||1;
obj?.[prop]; obj.func?.()
void 執行表示式,返回一個 undefined void alert("void")
&,|,~,^,<<,>> 二進位制位的運算,32位數字的位運算
delete 刪除一個物件的屬性、陣列鍵值,刪除後會變為undefined delete objt.pro
typeof 獲取資料型別,typeof (operand),括號省略。 typeof null; //object
in 判斷屬性是否在物件中 "length" in [] //true
instanceof 判斷物件是否指定的型別,用於引用型別、自定義型別 [] instanceof Array //true
new new Object()建立物件例項
superIE? 呼叫一個物件父類的函式,在子類中呼叫 supper.print();

05、邏輯語句

if/switch條件判斷

if條件語句,根據條件執行。if可單獨使用,也可以跟else if (0個或多個,中間)、else(0個或1個,放最後)。

if (條件) { /*程式碼*/ }
else if(條件) { /*程式碼*/ }
else if(條件) { /*程式碼*/ }
else { /*程式碼*/ }  //可以不要else部分,單獨if

switch定值條件分支,值的判斷是用的===恆等比較,多用於列舉值、固定的常量值。注意每一個case後需要用break,以防止穿透(繼續往後執行)。

switch (表示式) {
    case 值1:
        /*程式碼*/;
        break;     //返回,結束switch,防止無意義的穿透執行
    case 值2:
    case 值3:      //可以多case合併一塊
        /*程式碼*/;
        break;
    default:      //前面的case都沒有命中時執行
        /*程式碼*/
}

try.catch異常處理

try...catch...finally 語句捕獲異常,throw語句丟擲一個異常。

  • JS程式碼如果發生了異常,則不會再執行後面的程式碼了,就需要做好異常捕獲處理。
  • finally 語句塊為可選,不管是否丟擲異常都會執行,常用來做一些清理收尾工作。
  • throw丟擲異常,可以是自定義的值、物件,可以用Error物件包裝一個錯誤資訊。
function print(para) {
    if (para <= 0) {
        throw "引數para必須大於0(para= "+para+")";
        throw new Error("引數para必須大於0(para= "+para+")");
    }
    console.log(para);
}
print(2);   //如果這裡引數用-2,則會丟擲異常,這裡的異常沒人管,後面的程式碼就不會執行了
try{        //try包裝要執行的程式碼
    print(-2);
}
catch(e){   //catch捕獲try中丟擲的異常並處理,引數為捕獲到的異常資訊,如果沒有異常則跳過catch語句
    console.log("發生錯誤:" + e);
}
finally{
    console.log("執行完畢!")    //始終會被執行的程式碼,用於一些清理收尾工作
}

break/continue

  • break結束迴圈,停止本層迴圈,跳出本層迴圈,大家都別幹了!
  • continue結束本次迴圈,暫停本次迴圈,不執行後面的程式碼了,繼續下一次迴圈,我不想幹了,你們繼續!

while(true) { }

while迴圈,先判斷,符合條件才執行,會迴圈的判斷條件 執行,所以必須注意結束迴圈的控制,不然就是死迴圈了。

while(條件表示式){
    /*迴圈程式碼*/
    //條件控制程式碼,別忘了
}

do{ } while (true)

do...white迴圈,先執行 再判斷。同while,需注意迴圈的控制,避免死迴圈。

do{
    /*迴圈程式碼*/
    //條件控制程式碼,別忘了
}while(條件表示式)

for(i,i<n,i++){ }迴圈

迴圈執行邏輯控制語句:

for(初始化語句;判斷條件語句;控制條件語句){
    /*迴圈程式碼*/
}
for(let i=1;i<=10;i++){ //迴圈1到10
    if(i>6)
        break; //跳出並結束迴圈
    if(i%2==1)
        continue;   //如果是奇數,返回繼續下一次迴圈
    console.log(i);     
}

for(in){ }可列舉屬性

for...in迴圈,對一個物件(不僅僅是陣列)進行迴圈遍歷,遍歷其所有可列舉的屬性(索引下標、屬性),包括繼承來的。

let arr=[1,2];
arr.uname="arr";
arr.print=function(){console.log(this.length)};
for(let i in arr){
    console.log(i+":"+arr[i]);
}
/*輸出:
0:1
1:2
uname:arr
print:function(){console.log(this.length)}
*/

❗慎用 for(in):for(in)是迴圈遍歷的是所有可列舉的(enumerable)屬性,對於陣列、可迭代集合一般使用for(of)

for(of) {}集合值迭代

for…of(IE?)語法是ES6新引入的語法,用於遍歷可迭代(iterable)物件,只遍歷陣列物件元素。包括字串String、陣列Array、集合Set、字典Map、arguments 物件、DOM NodeList 物件等。

for...in最大的區別就是,for...of迭代的是集合的資料值,而不是可列舉屬性(索引)。

let arr=[1,2];
arr.uname="arr";
arr.print=function(){console.log(this.length)};
for(let i of arr){
    console.log(i); //1  2
}

forEach()陣列方法

forEach 作用於陣列物件,用於遍歷陣列物件的每一個元素,並對每一個元素執行回撥(callback)函式。

語法:ArrayObject.forEach(callback(currentValue, index, arr), thisValue))

let arr = [1, 2];
arr.uname = "arr";
arr.print = function () { console.log(this.length) };
arr.forEach(function (item, index) {
    console.log(index + ":" + item);
});
/*輸出: 
0:1
1:2
*/

©️版權申明:版權所有@安木夕,本文內容僅供學習,歡迎指正、交流,轉載請註明出處!原文編輯地址-語雀

相關文章