JavaScript
簡介
JavsScript 于 1995 年由 Brendan Eich 用時 10 天寫出,用于網景瀏覽器,最初的名字叫 LiveScript,也被部分員工稱為 Mocha,那時 Java 語言很流行,出于商業化的考量,更名為 JavaScript,但兩者之間沒有關聯,
最早的 JS 作為腳本語言給瀏覽器增加一些諸如滑鼠跟隨等互動性特效,通過在 HTML 中添加 <script> 元素實作,
1996 年網景和 ECMA 達成了協議,起草 JS 的規范,第一版規范由 ECMA 做出并于 1997 釋出,這個規范被稱為 ECMA-262 標準,
JS 并不是一個獨立的物體,它僅存在于實作中,這個實作稱為 JS 引擎,
傳統的 JS 引擎環境就是瀏覽器,確切來說,JS 引擎是瀏覽器的一個構建塊,
此外,JS 引擎本身也可以和瀏覽器的其他部分互動,這些部分被稱為瀏覽器 API,
所以 JS 代碼有兩個功能:
- 和瀏覽器中的 JS 引擎互動
- 和瀏覽器中的 JS 引擎外的其他部分互動
隨后在 2009 年,Ryan Dahl 發布了 Node.js,他把 JS 引擎作為一個獨立的物體,使得 JS 可以在瀏覽器外,作為服務端環境運行,
幾種類似 JavaScript 的語言
- JScript
- VBScript
- TypeScript
為什么選擇 JavaScript
- 目前最流行的語言之一
- 瀏覽器唯一編程語言
- 使用者數量多
- 容易使用
- 無處不在
- 純 JavaScript (Vanilla JS / Plain JS)
- UI 庫/框架(React/Vue/Angular/jQuery/Ember/Next)
- 服務端(Node/Deno/Bun)
- 移動端(React Native)
- 桌面端(Electron)
- 社區龐大
- 需求大
注釋
被注釋的代碼塊是不會執行的,
JavaScript有兩種寫注釋(comment)的方法,
- 使用
//注釋掉當前行的代碼, 這是一個行內注釋:
// This is an in-line comment.
- 也可以使用多行注釋,使用
/*開始,*/結束, 這是一個多行注釋:
/* this is a multi-line commment */
最佳實踐:應該添加注釋來解釋代碼的作用,適當的注釋能讓代碼更易懂,
分號
分號(semi-colon) ; 在 JavaScript 中用于表示一條陳述句的結尾,
console.log("hello world");
console.log("hello world")
瀏覽器有自動插入分號(Automatic Semi-Colon Insertion / ASI)的功能,所以不加分號瀏覽器也能正確識別陳述句的結尾,但是最佳實踐顯示,應該加上分號以提高代碼的可讀性,
變數 Variable
資料型別 Data Type
JavaScript 提供七種不同的基本型別(Primitive),分別是:
undefined未定義、null空、boolean布爾、string字串、symbol標志、number數字、bigint任意大的整數
基本型別不是物件(object),沒有方法(method)和屬性(property),
宣告 Declare
通過在變數前面使用關鍵字 var,宣告一個變數,例如:
var myName;//undefined
變數名稱可以由數字、字母、美元符號 $ 或者下劃線 _ 組成,但是不能包含空格或者以數字為開頭,
如果只宣告不賦值,那么值為 undefined,
字串變數 String
"your name" 被稱為字串字面量(string literal), 字串文字或字串是用單引號或雙引號括起來的一系列零個或多個字符,
與其他一些編程語言不同的是,單引號和雙引號的功能在 JavaScript 中是相同的,
字串在開頭和結尾都要有相同的引號,如果在中間使用了相同的引號,字串會提前中止并拋出錯誤,
'' // empty string
"" // empty string
var myFirstName = "Pete";
var myLastName = "Mitchell";
const conversation = 'Finn exclaims to Jake, "Algebraic!"';
var str = 'de'f'; // SyntaxError: Unexpected identifier
可迭代
在 JS 中,字串是可迭代(iterable)型別,指的是這種資料型別可以用回圈迭代,
字串也被稱為類陣列(array-like)型別,
字串的長度 Length
通過 .length 來獲得字串的長度,
let lastNameLength = 0;
const lastName = "Lovelace";
lastNameLength = lastName.length;
字串索引 Index
方括號表示法(Bracket notation)是一種在字串中的特定 index(索引)處獲取字符的方法,
大多數現代編程語言,是從 0 開始計數, 這被稱為基于零(Zero-based)的索引,
let firstLetterOfLastName = "";
const lastName = "Lovelace";
firstLetterOfLastName = lastName[0]; // 'L'
字串的不變性 Immutable
在 JavaScript 中,字串(String)的值是不可變的(immutable),這意味著一旦字串被創建就不能被改變,
例如:
let myStr = "Bob";
myStr[0] = "J";
是不會把變數 myStr 的值改變成 Job 的,因為變數 myStr 是不可變的, 注意,這并不 意味著 myStr 永遠不能被改變,只是字串字面量 string literal 的各個字符不能被改變, 改變 myStr 的唯一方法是重新給它賦一個值,例如:
let myStr = "Bob";
myStr = "Job";
字串中的字符
為了讀取從 0 開始某特定位置的字符,使用 charAt() 方法:
var greet = 'hello';
greet.charAt(0) // h
字串拼接
字串拼接方法 concat() :
"Wo".concat("rl").concat("d") # World
獲得某字符的索引
使用 indexOf() 獲得某字符在字串中的索引位置,如果不包含該字符,則回傳 -1,如果包含多個相同字符,則回傳第一個字符出現的位置;lastIndexOf() 回傳相同字符出現的最后一個位置:
'greet'.indexOf('g') // 0
'greet'.indexOf('e') // 2
'greet'.indexOf('a') // -1
'cace'.lastIndexOf('c'); // 2
Undefined & Null
undefined 資料型別只有一個值:undefined,
- 所有函式默認回傳
undefined,除非顯式回傳一個值, - 訪問物件不存在的屬性,回傳
undefined - 已宣告但未賦值的變數,
undefined
當 JavaScript 中的變數被宣告的時候,程式內部會給它一個初始值 undefined, 當對一個值為 undefined 的變數進行運算操作的時候,算出來的結果將會是 NaN,它的意思是 "Not a Number", 當用一個值是 undefined 的變數來做字串拼接操作的時候,它會轉換成字串(string)undefined,
null 指代缺少(absence)值,undefined 指代未賦值,
var str = 'abc';
str.match(/d/); // null
var str2; // undefined
變數名區分大小寫 Case Sensitivity
最佳實踐:使用駝峰命名法(camelCase)來命名一個 Javascript 變數, 在駝峰命名法中,變數名的第一個單詞的首字母小寫,后面的單詞的第一個字母大寫,
var someVariable;
var anotherVariable;
var 和 let
使用 var 關鍵字(keywords)宣告變數存在的問題:
- 在宣告前就可以被使用
- 相同的變數可以再次宣告
- 可以在全域或者函式內部的作用域起作用
// 第一種
console.log(user); // mike
var user = 'mike';
// 第二種
var camper = "James";
var camper = "David";
console.log(camper); // David
ES6 中引入了一個名為 let 的關鍵字,這是對 JavaScript 的一次重大更新,以解決與 var 關鍵字有關的潛在問題,
如果將上面代碼中的 var 替換為 let ,則會導致錯誤,使用 let 時,同名的變數只能宣告一次,
const
const 具有 let 的所有功能,另外還有一個額外的好處,即使用 const 宣告的變數是只讀(Read-only)的, 它們是一個常量值(constant),這意味著一旦一個變數被賦值為 const,它就不能被重新賦值:
const FAV_PET = 'cats';
FAV_PETS = 'dogs'
// this line will cause a error;
命名常量的常見做法是全部使用大寫字母,單詞之間用下劃線分隔,
小數 Decimal
小數有時候也被稱作浮點數或者 floats,
提示: 不是所有的實數都可以用浮點數(floating point)來表示, 因為可能產生四舍五入的錯誤,
var myDecimal = 5.7;
布林值 Boolean
布林值只能是兩個值中的一個:true 或者 false,
布林值是不帶引號的, 字串 "true"和 "false" 不是布林值,在 JavaScript 中也沒有特殊含義,
function welcomeToBooleans() {
return true;
}
真值 假值
真值(Truthy)和假值(Falsy)指的是在布林值的背景關系中,轉換后為 true 和 false 的值,
所有除 false、0、-0、0n、""、null、undefined 和 NaN 以外的皆為真值),
if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
JS 中有 8 個假值:
| 值 | 說明 |
|---|---|
false |
false 關鍵字 |
| 0 | 數值 zero |
| -0 | 數值 負 zero |
| 0n | 當 BigInt 作為布林值使用時,遵從其作為數值的規則. 0n 是 falsy 值, |
| "", '', `` | 這是一個空字串 (字串的長度為零). JavaScript 中的字串可用雙引號 "", 單引號 '', 或 模板字面量 ```` 定義, |
| null | null - 缺少值 |
| undefined | undefined - 原始值 |
| NaN | NaN - 非數值 |
BigInt Symbol
這兩個資料型別是 ES6 引入的,BigInt 用于表示更大的數字,Symbol 用于表示統一識別符號,
數字 Number
數字型別可以表示整數(integer) 或者小數(decimal),
運算 Operation
賦值 Assignment
使用賦值(assignment)運算子 = 將值存盤在變數中,
var myVariable = 5; // 直接賦值
var myCode; // 先宣告后賦值
myCode = 100;
在賦值后,可使用賦值運算子將某變數的值賦給另一個變數,
var myVariable = 5;
var b;
b = myVariable;
加法 Add
var sum = 10 + 1; // sum = 11;
拼接 Concatenate
當 + 運算子被用于一個 String型別的值的時候,它被稱作拼接運算子,
const myStr = "This is the start." + " " + "This is the end."; // myStr "This is the start This is the end"
如果一個數字和字串做拼接,JS 會把數字轉化為字串然后再拼接,最后得到一個字串:
365 + " days" // "365 days"
1 + "2" // "12"
這種看不見(under-the-hood)的轉換稱為“強制型別轉換(coercion)”,
減法 Subtract
var difference = 10 - 2; // 8
乘法 Multiply
var product = 1 * 2; // 2
除法 Divide
var quotient = 10 / 2; // 5
自增 Increment
var my = 1;
my++; // my 2
自減 Decrement
var my = 2;
my--; // my 1
求余 Reminder
求余運算子(The modulus operator) % 回傳兩個數相除得到的余數
用法
在數學中,判斷一個數是奇數還是偶數,只需要判斷這個數除以 2 得到的余數是 0 還是 1,
提示
余數運算子(remainder)有時被錯誤地稱為“模數”運算子, 它與模數非常相似,但不能用于負數的運算,
let remainder = 11 % 3; // 2
求冪 Exponentiation
求冪運算子 ** 回傳某底數的次冪
let exp = 10 ** 2 // 100
復合賦值 Compound Assignment
+=,-=,*=,`/=``
+= 稱為“addition assignment operator,
還可以使用 += 運算子來拼接字串到現有字串變數的結尾,
let myVar = 1;
myVar += 5;
myVar -= 1;
myVar *= 1;
myVar /= 1;
let myStr = "This is the first sentence.";
myStr += " ";
myStr += "This is the second sentence."
相等 Equality Operator
相互比較的操作都回傳一個 true 或 false 值,
最基本的運算子是相等運算子:==,
在 JavaScript 中,為了讓兩個不同的資料型別(例如 numbers 和 strings)的值可以作比較,它必須把一種型別轉換為另一種型別, 這叫作 “型別強制轉換”, 轉換之后,可以像下面這樣來比較:
1 == 1 //true
1 == 2 //false
1 == '1' //true
"3" == 3 //true
嚴格相等 Strict Equality Operator
嚴格相等運算子不會做型別轉換,如果比較的值型別不同,那么在嚴格相等運算子比較下它們是不相等的,會回傳 false ,
3 === 3 //true
3 === '3' //false
不等 Inquality Opeartor
不相等運算子(!=)與相等運算子是相反的, 不相等運算子在比較的時候也會轉換值的資料型別,
1 != 2 // true
1 != "1" // false
1 != '1' // false
1 != true // false
0 != false // false
嚴格不等 Strict Inequality Operator
嚴格不相等運算子(!==)與全等運算子是相反的, 嚴格不相等運算子不會轉換值的資料型別,
3 !== 3 // false
3 !== '3' // true;
4 !== 3 // true;
大于 Greater Than Operator
使用大于運算子(>)來比較兩個數字, 如果大于運算子左邊的數字大于右邊的數字,將會回傳 true, 否則,它回傳 false,
大于運算子在比較的時候,會轉換值的資料型別,
5 > 3 // true;
7 > '3' // true;
2 > 3 // false;
'1' > 9 // false;
大于等于 Greater Than Or Equal To Operator
使用大于等于運算子(>=)來比較兩個數字的大小, 如果大于等于運算子左邊的數字比右邊的數字大或者相等,會回傳 true, 否則,會回傳 false,
大于等于運算子在比較的時候會轉換值的資料型別,
6 >= 6 // true
7 >= '3' // true
2 >= 3 // false
'7' >= 9 // false
小于 Less Than Operator
使用小于運算子(<)來比較兩個數字, 如果小于運算子左邊的數字比右邊的數字小,它會回傳 true, 否則會回傳 false, 小于運算子在做比較的時候會轉換值的資料型別,
2 < 5 // true
'3' < 7 // true
5 < 5 // false
3 < 2 // false
'8' < 4 // false
小于等于 Less Than Or Equal To Operator
使用小于等于運算子(<=)比較兩個數字的大小, 如果在小于等于運算子左邊的數字小于或者等于右邊的數字,它會回傳 true, 如果在小于等于運算子左邊的數字大于右邊的數字,它會回傳 false,小于或等于運算子會轉換資料型別,
4 <= 5 // true
'7' <= 7 // true
5 <= 5 // true
3 <= 2 // false
'8' <= 4 // false
邏輯與 Logical And Opeator
當且僅當運算子的左邊和右邊都是 true,邏輯與運算子(&&)才會回傳 true,
該運算子可用于兩個比較運算:
if (val <= 50 && val >= 25) {
return "Yes";
}
邏輯或 Logical Or Operator
只要邏輯或運算子(||)兩邊的任何一個運算的結果是 true,則回傳 true, 否則,回傳 false,
if (val <= 10 || val >= 20) {
return "Outside";
}
邏輯非 Logical Not Operator
當結果為 true ,邏輯非(!)回傳 false;反之回傳 true,
var a = 6
a > 5 # true
!(a > 5) # false
三元運算子 Ternary Operator
條件運算子( conditional operator,)(也稱為三元運算子( ternary operator))語法是:a ? b : c, where a 是條件,當條件回傳 true 的時候運行代碼 b,當條件回傳 false 的時候運行代碼 c,
function checkEqual(a, b) {
return a === b ? "Equal" : "Not Equal";
}
確定型別 Typeof
使用 typeof 運算子確定變數或值的型別
typeof 3 // number
typeof '3' // string
typeof [] // object
typeof {} // object
優先級和結合律
優先級(precedence)決定了運算的先后次序,結合律(associativity)決定了在優先級相同的情況下,運算的左右順序,
有兩種結合律:
- 從左到右
- 從右到左
轉義 Escape
定義一個字串必須要用單引號或雙引號來包裹它, 那么當字串里面包含引號 " 或者 ' 時,在 JavaScript 中,可以通過在引號前面使用反斜杠(\)來轉義引號,
const myStr = "I am a \"double quoted\" string inside \"double quotes\".";
轉義字符 Escape Sequence
引號不是字串中唯一可以被轉義(escaped)的字符, 使用轉義字符有兩個原因:
- 首先是可以使用無法輸入的字符,例如退格,
- 其次是可以在一個字串中表示多個引號,而不會出錯,
| 代碼 | 輸出 |
|---|---|
\' |
單引號 |
\" |
雙引號 |
\\ |
反斜杠 |
\n |
換行符 |
\r |
回車符 |
\t |
制表符 |
\b |
退格 |
\f |
換頁符 |
請注意,必須對反斜杠本身進行轉義,它才能顯示為反斜杠,
const myStr = "FirstLine\n\t\\SecondLine\nThirdLine";
條件 Conditional
條件陳述句也被稱為控制流陳述句(flow control statement),
if else
if 陳述句用于在代碼中做出決定,
當條件的計算結果為 true,程式執行大括號內的陳述句, 當布爾條件的計算結果為 false,大括號內的代碼將不會執行,使用 else 陳述句,可以執行當條件為假時相應的代碼,
如果有多個條件陳述句,通過 else if 陳述句把 if 陳述句鏈起來,
function trueOrFalse(wasThatTrue) {
if (wasThatTrue) {
return "Yes, that was true";
}
else {
return "No, that was false";
}
}
switch
switch 評估一個運算式,將運算式的值與 case 子句匹配, 從第一個匹配的 case 值執行陳述句,直到遇到 break,
case 值使用嚴格相等(===)運算子進行比較, 注意 case 的值,1 匹配數字 1,'1' 匹配字串 '1',break 告訴 JavaScript 停止執行 switch 陳述句, 如果遺漏了 break ,下一個陳述句將會被執行,
在 switch 陳述句中,可能無法用 case 列舉出所有可能的值, 相反,添加 default 陳述句,它會在找不到相匹配的 case 陳述句之后執行, 可以把它看作是 if/else 鏈中最后的那個 else 陳述句,
default 陳述句應該被放到最后,
function switchOfStuff(val) {
let answer = "";
switch(val) {
case 'a': answer = "apple"; break;
case 'b': answer = "bird"; break;
case 'c': answer = "cat"; break;
default : answer = "stuff"; break;
}
return answer;
}
switchOfStuff(1); // stuff
如果想為 switch 中的多個不同的輸入設定相同的結果,可以這樣寫:
function sequentialSizes(val) {
let answer = "";
switch(val) {
case 1:
case 2:
case 3: answer = "Low"; break;
case 4:
case 5:
case 6: answer = "Mid";
break;
case 7:
case 8:
case 9: answer = "High";break;
}
return answer;
}
sequentialSizes(1); // Low
回圈 Loop
while
當 while 指定的條件為真,回圈才會執行,反之不執行,
const myArray = [];
let i = 5;
while (i <= 5 && i >= 0) {
myArray.push(i);
i--;
}
上面的 i 稱為計數器(counter),
for
最常見的回圈就是 for,它可以回圈指定次數,
for 回圈中的可選三個運算式用分號隔開:
for (a; b; c),其中 a 為初始化陳述句,b 為條件陳述句,c 是最終的運算式,
初始化陳述句只會在執行回圈開始之前執行一次, 它通常用于定義和設定回圈變數,
回圈條件陳述句會在每一輪回圈的開始前執行,只要條件判斷為 true 就會繼續執行回圈, 當條件為 false 的時候,回圈將停止執行, 這意味著,如果條件在一開始就為 false,這個回圈將不會執行,
終止回圈運算式在每次回圈迭代結束, 在下一個條件檢查之前時執行,通常用來遞增或遞級訓圈計數,
const myArray = [];
for (let i = 1; i <= 5; i++) {
myArray.push(i);
}
for-of
for-of 回圈可用在可迭代物件中:
const colors = ['red', 'blue', 'yellow'];
for (var color of colors) {
console.log(color);
}
do-while
它被稱為 do...while 回圈,是因為不論什么情況,它都會首先 do(運行)回圈里的第一部分代碼,然后 while(當)規定的條件被評估為 true(真)的時候,它會繼續運行回圈,
const myArray = [];
let i = 10;
do {
myArray.push(i);
i++;
} while (i < 11);
嵌套回圈
如果有一個二維陣列,可以使用相同的邏輯,先遍歷外面的陣列,再遍歷里面的子陣列,
let myArray = [[1, 2], [3, 4]];
for (let i = 0; i < myArray.length; i++) {
for (let j = 0; j < myArray[i].length; j++) {
console.log(myArray[i][j]);
}
}
函式 Function
把代碼的重復部分抽取出來,放到一個函式 (function)中,
通過函式名加上后面的小括號來呼叫(invoke / call)這個函式,就像這樣: functionName();
每次呼叫函式時,大括號之間的所有代碼都將被執行,
function reusableFunction() {
console.log("Hi World");
}
reusableFunction(); // Hi World
傳參 Passing value with Argument
函式的引數 (parameters)在函式呼叫中充當傳入函式的輸入占位符(也叫形參), 函式呼叫時,引數可以為一個或多個, 呼叫函式時輸入(或傳遞 "passed")的實際值被稱為引數(arguments),
function functionWithArgs(a,b) {
console.log(a + b);
}
functionWithArgs(3, 4); // 7
回傳值 Return Value
使用 return 陳述句把資料從一個函式中傳出來,
function timesFive(a) {
return a * 5;
}
timesFive(1); // 5
在函式沒有 return 陳述句的情況下,當呼叫它時,該函式會執行內部代碼,回傳的值是 undefined,
let sum = 0;
function addThree() {
sum = sum + 3;
}
function addFive() {
sum += 5;
}
addThree();
addFive();
作用域和函式 Scope
全域作用域 Gobal Scope
在 JavaScript 中,作用域涉及到變數的作用范圍, 在函式外定義的變數具有 全域 作用域, 具有全域作用域的變數可以在代碼的任何地方被呼叫,
未使用 let 或 const 關鍵字宣告的變數會在 global 范圍內自動創建, 當在代碼其他地方無意間定義了一個變數,剛好變數名與全域變數相同,這時會產生意想不到的后果, 應該總是用 let 或 const 宣告變數,
區域作用域 Local Scope
在一個函式內宣告的變數,以及該函式的引數都具有區域(local)作用域, 這意味著它們只在該函式內可見,
在 ES5 中,只有函式能創建區域作用域;ES6 中,使用 let 和 const 可以創建塊級作用域(block scope),塊級作用域是被宣告變數所屬的塊,如果在函式外就是全域,如果函式內就是塊級或者區域,
function test(a) {
let a = 3;
console.log(a);
}
// 3;
console.log(a);
// Reference Error;
優先級
一個程式中有可能具有相同名稱的區域變數和全域變數, 在這種情況下,區域變數將會優先于全域變數,
const outerWear = "T-Shirt";
function myOutfit() {
const outerWear = "sweater";
return outerWear;
}
myOutfit(); // sweater
陣列 Array
在 JS 中,array 也是 object,有內置方法和屬性,
使用陣列(array)存盤多個資料,以左方括號開始定義一個陣列,以右方括號結束,里面每個元素之間用逗號隔開,
const myArray = [0, 1, "code"];
多維陣列 Multi-Dimensional Array
在其他陣列中嵌套陣列,這也叫做多維陣列(multi-dimensional array)
const myArray = [["html","css"],"javascript"];
索引訪問 Index Access
使用索引(indexes)來訪問陣列中的資料,陣列索引與字串一樣使用方括號來表示,不同的是,它們不是指定字符,而是指定陣列中的一個條目, 陣列索引與字串索引一樣是從 0 開始(zero-based)的,注意:陣列名與方括號之間不應該有任何空格,比如array [0] ,
const myArray = [50, 60, 70];
var myData = https://www.cnblogs.com/risejl/p/myArray[0]; // 50
訪問嵌套陣列
與訪問嵌套物件類似,陣列的方括號可以用來對嵌套陣列進行鏈式訪問,
const myPlants = [
{
type: "flowers",
list: [
"rose",
"tulip",
"dandelion"
]
},
{
type: "trees",
list: [
"fir",
"pine",
"birch"
]
}
];
const secondTree = myPlants[1].list[1]; // pine
索引修改 Index Modify
與字串不同,陣列的條目是 可變的 并且可以自由更改,即使陣列是用 const 宣告的,
const myArray = [18, 64, 99];
myArray[0] = 45; // [45,64,99]
訪問多維陣列
使用方括號表示法訪問陣列時,第一個方括號訪問的是陣列的最外層(第一層),第二個方括號訪問的是陣列的第二層,以此類推,
const myArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[[10, 11, 12], 13, 14],
];
const myData = https://www.cnblogs.com/risejl/p/myArray[2][1]; // 8;
push()
將資料添加到陣列末尾的簡單方法是 push()函式,
.push() 接受一個或多個引數(parameters),并把它壓入到陣列的末尾,
const myArray = [["John", 23], ["cat", 2]];
myArray.push(["dog", 3]); // [["John", 23], ["cat", 2],["dog", 3]]
pop()
.pop() 函式移除陣列末尾的元素并回傳這個元素,
const myArray = [["John", 23], ["cat", 2]];
let removedFromMyArray = myArray.pop(); // ["cat", 2]
shift()
shift()移除的是第一個元素,
const myArray = [["John", 23], ["dog", 3]];
const removedFromMyArray = myArray.shift(); // ["John", 23]
unshift()
unshift(移入)一個元素到陣列的頭部,
const myArray = [["John", 23], ["dog", 3]];
myArray.unshift(["Paul", 35]); // ["Paul", 35]],[["John", 23],["dog", 3]
splice()
splice() 可以從陣列中的任意位置連續洗掉任意數量的元素,
splice() 最多可以接受 3 個引數,
splice() 接收的前兩個引數是整數,表示正在呼叫的splice() 陣列中的元素的索引或位置, splice() 的第一個引數代表從陣列中的哪個索引開始移除元素,而第二個引數表示要從陣列中的這個位置開始洗掉多少個元素,
splice() 不僅會修改呼叫該方法的陣列,還會回傳一個包含被移除元素的陣列:
const arr = [2, 4, 5, 1, 7, 5, 2, 1];
arr.splice(1, 4);
console.log(arr);
第三個引數可以是一個或多個元素,這些元素會被添加到陣列中, 這樣,能夠便捷地將陣列中的一個或多個連續元素換成其他的元素,
function htmlColorNames(arr) {
arr.splice(0, 2, "DarkSalmon", "BlanchedAlmond");
return arr;
}
console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurquoise', 'FireBrick']));
slice()
slice() 不會修改陣列,而是會復制,或者說提取(extract)給定數量的元素到一個新陣列, slice() 只接收 2 個輸入引數:第一個是開始提取元素的位置(索引),第二個是提取元素的結束位置(索引), 提取的元素中不包括第二個引數所對應的元素,
function forecast(arr) {
return arr.slice(2, 4);
}
console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));
展開運算子...
展開運算子復制陣列
let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];
展開運算子合并陣列
展開語法(spread)的另一個重要用途是合并陣列,或者將某個陣列的所有元素插入到另一個陣列的任意位置,
let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];
let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];
forEach
forEach 方法接收一個函式,該函式會在每一個陣列項中執行,該函式的第一個引數是當前陣列元素本身,第二個引數是索引(可選引數),
const fruits = ['kiwi','mango','apple','pear'];
function appendIndex(fruit,index) {
console.log(`${index}.${fruit}`)
}
fruits.forEach(appendIndex);
通常會把 forEach 接收的函式體直接寫入函式呼叫中:
const fruits = ['kiwi','mango','apple','pear'];
fruits.forEach(function(fruit, index) {
console.log(`${index}.${fruit}`)
})
filter()
類似 forEach ,該方法用于每一個陣列項,它會根據傳入函式回傳一個過濾后的陣列:
const nums = [100,200,30,40,10,0];
nums.filter(function (item) {
return item > 100;
})
// [200]
map()
該方法根據傳入的函式,把某陣列的值按照函式規則映射(map)到另一陣列:
[0,10,20,30].map(function (num) {
return num ** 2;
}) // [0, 100, 400, 900]
物件 Object
物件(object)本質上是鍵值對(key-value pair)的集合, 或者說,一系列被映射到唯一識別符號的資料就是物件;習慣上,唯一識別符號叫做屬性(property)或者鍵(key);資料叫做值(value),
JS 中常用物件字面量語法 {} 來創建一個物件,
var user = {};
也可以把屬性和值以鍵值對的形式直接宣告來創建物件:
const myDog = {
"name": "Good",
"legs": 4,
"tails": 1,
"friends": ["code", "fads"]
};
物件和arrays類似,區別在于陣列使用索引來訪問和修改資料,而物件中資料是通過屬性訪問的,
物件非常適合用來存盤結構化資料,屬性都存盤為字串,也可以使用數字作為屬性,甚至可以省略單字字串屬性中的引號,
然而,如果物件有非字串屬性的話,JavaScript 會自動將它們轉為字串,
in
JavaScript 提供了兩種不同的方式來檢查物件是否有某個屬性: 一個是通過 hasOwnProperty() 方法,另一個是使用 in 關鍵字,
users.hasOwnProperty('Alan'); // true
'Alan' in users; // true
for ... in 遍歷物件
物件是不可迭代的,所以不能直接使用 for 和 for-of 回圈,
const car = {
speed: 100,
color: 'blue'
}
for (prop of car) {
console.log(prop);
}
// Uncaught TypeError: car is not iterable
遍歷物件中的所有屬性, 只需要使用 JavaScript 中的 for...in 陳述句即可,
for-in 物件遍歷物件和其原型的屬性;for-of 僅遍歷物件自身的屬性,
let car = {
speed: 100,
engine: 'true'
}
let car2 = Object.create(car);
for (prop of car2) { console.log(prop); } // Uncaught TypeError: car2 is not iterable
for (prop in car2) {
console.log(prop);
} // color speed engine 順序不固定
for (key of Object.keys(car2)) {
console.log(key);
} // color
注意:物件中的鍵是無序的,這與陣列不同, 因此,一個物件中某個屬性的位置,或者說它出現的相對順序,在參考或訪問該屬性時是不確定的,
for (let user in users) {
console.log(user);
}
Object.keys()
給 Object.keys() 方法傳入一個物件作為引數,來生成包含物件所有鍵的陣列, 這會回傳一個由物件中所有屬性(字串)組成的陣列, 需要注意的是,陣列中元素的順序是不確定的,
let users = {
Alan: {
age: 27,
online: false
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: false
},
Ryan: {
age: 19,
online: true
}
};
function getArrayOfUsers(obj) {
return Object.keys(obj);
}
console.log(getArrayOfUsers(users));
// [ 'Alan', 'Jeff', 'Sarah', 'Ryan' ]
遍歷物件中的屬性和值:
var clothingItem = {
price: 50,
color: 'beige',
material: 'cotton',
season: 'autumn'
}
for (key of Object.keys(clothingItem)) {
console.log(keys, ":", clothingItem[key]);
}
Object.values()
給 Object.values() 方法傳入一個物件作為引數,來生成包含物件所有值的陣列, 這會回傳一個由物件中所有屬性的值組成的陣列,
const car3 = {
speed: 300,
color: 'yellow'
}
console.log(Object.values(car3)); // [300,'yellow']
Object.entries()
給 Object.entries() 方法傳入一個物件作為引數,來生成包含物件所有鍵值對的陣列,
const car4 = {
speed: 400,
color: 'magenta'
}
console.log(Object.entries(car4)); // [ ['speed', 400], ['color', 'magenta'] ]
訪問屬性 Access Property
訪問物件屬性有兩種方式:點號表示法(.)和方括號表示法([])
點號訪問 Dot Notation
如果提前知道要訪問的屬性名,使用點號表示法是最方便的,
const testObj = {
"hat": "ballcap",
"shirt": "jersey",
"shoes": "cleats"
};
const hatValue = https://www.cnblogs.com/risejl/p/testObj.hat; // ballcap
const shirtValue = testObj.shirt; // jersey
方括號訪問 Bracket Notation
訪問物件屬性的第二種方式是方括號表示法([]),這種方法需要把屬性作為字串寫入方括號內,如果要訪問的屬性名中包含空格,就必須使用方括號表示法來獲取它的屬性值,
const testObj = {
"an entree": "hamburger",
"my side": "veggies",
"the drink": "water"
};
const entreeValue = https://www.cnblogs.com/risejl/p/testObj["an entree"];
const drinkValue = https://www.cnblogs.com/risejl/p/testObj["the drink"];
最后,方括號訪問比點號訪問的優勢是:可以計算運算式,
var arrOfKeys = ['speed', 'altitude', 'color'];
var drone = {
speed: 100,
altitude: 200,
color: 'red'
}
for (var i = 0; i < arrOfKeys.length; i++) {
console.log(drone[arrOfkeys[i]]);
}
/*
100
200
red
*/
變數訪問
還可以訪問物件上作為變數值存盤的屬性, 當需要遍歷物件的所有屬性,或者根據一個變數的值查找對應的屬性值時,這種寫法尤其適用,
const dogs = {
Fido: "Mutt",
Hunter: "Doberman",
Snoopie: "Beagle"
};
const myDog = "Hunter";
const myBreed = dogs[myDog];
console.log(myBreed); // Doberman
使用這一概念的另一種情況是:屬性的名字是在程式運行期間動態收集得到的,
const someObj = {
propName: "John"
};
function propPrefix(str) {
const s = "prop";
return s + str;
}
const someProp = propPrefix("Name");
console.log(someObj[someProp]);
注意,當使用變數名訪問屬性時,沒有 使用引號包裹它,因為使用的是變數的值,而不是變數的名字,
const testObj = {
12: "Namath",
16: "Montana",
19: "Unitas"
};
const playerNumber = 16;
const player = testObj[playerNumber]; // Montana
嵌套訪問
通過連續使用點號表示法和方括號表示法來訪問物件的嵌套屬性,
const myStorage = {
"car": {
"inside": {
"glove box": "maps",
"passenger seat": "crumbs"
},
"outside": {
"trunk": "jack"
}
}
};
const gloveBoxContents = myStorage.car.inside["glove box"]; // maps
更改屬性 Update
創建了 JavaScript 物件后,可以隨時更新它的屬性, 使用點或中括號運算子來更新,
const myDog = {
"name": "Coder",
"legs": 4,
"tails": 1,
"friends": ["freeCodeCamp Campers"]
};
myDog["name"] = "Happy Coder";
添加屬性 Add
使用點號來更新,給 JavaScript 物件添加屬性,
可以給物件添加多種資料型別的屬性,包括函式;如果添加了函式屬性,就稱為“方法”,
const myDog = {
"name": "Happy Coder",
"legs": 4,
"tails": 1,
"friends": ["freeCodeCamp Campers"]
};
myDog.bark = "woof";
myDog.call = function() {
console.log('hello');
}
洗掉屬性 Delete
可以使用 delete 洗掉物件的屬性
const myDog = {
"name": "Happy Coder",
"legs": 4,
"tails": 1,
"friends": ["freeCodeCamp Campers"],
"bark": "woof"
};
delete myDog.tails;
檢查物件屬性 Test
用物件的 .hasOwnProperty(propname) 方法來檢查物件是否有指定的屬性, .hasOwnProperty() 找到該屬性時回傳 true,找不到該屬性時回傳 false,
obj.hasOwnProperty(check);
復雜物件 Complex Object
提示:陣列中有多個 JSON 物件的時候,物件與物件之間要用逗號隔開,
const myMusic = [
{
"artist": "Billy Joel",
"title": "Piano Man",
"release_year": 1973,
"formats": [
"CD",
"8T",
"LP"
],
"gold": true
},
{
"artist": "Mitchell",
"title": "Cocomo",
"release_year": 1900,
"formats": [
"fds",
"Fsdf"
]
}
];
遞回 Recursion
遞回是函式呼叫自身的操作,
function sum(arr, n) {
if (n <= 0) return 0;
else return sum(arr, n - 1) + arr[n-1];
}
Math 庫
常用的常量
- PI 值:
Math.PI - 歐拉數 Euler 常量:
Math.E - 2 的自然對數:
Math.LN2
舍入方法
Math.ceil()無論小數部分如何,向上舍入到最接近的整數Math.floor()無論小數部分如何,向下舍去到最接近的整數Math.round()如果小數部分大于.5,向上舍入到最接近的整數 ,否則向下舍去最接近整數Math.trunc()去掉小數部分,僅留下整數部分
console.log(Math.ceil(2.3)); // 3
console.log(Math.ceil(2.7)); // 3
console.log(Math.floor(2.3)); // 2
console.log(Math.floor(2.7)); // 2
console.log(Math.round(2.3)); // 2
console.log(Math.round(2.7)); // 3
console.log(Math.trunc(2.3)); // 2
console.log(Math.trunc(2.7)); // 2
隨機分數 Random
亂數非常適合用來創建隨機行為,
在 JavaScript 中,可以用 Math.random() 生成一個在0(包括 0)到 1(不包括 1)之間的隨機小數,
function randomFraction() {
return Math.random();
}
隨機整數
- 用
Math.random()生成一個隨機小數, - 把這個隨機小數乘以
20, - 用
Math.floor()向下取整,獲得它最近的整數,
記住 Math.random() 永遠不會回傳 1,同時因為是在向下取整,所以最侄訓得的結果不可能有 20, 這確保了我們獲得了一個在 0 到 19 之間的整數,
function randomWholeNum() {
return Math.floor(Math.random() * 10);
}
生成某個范圍內的數字
需要定義一個最小值 min 和一個最大值 max,
function randomRange(myMin, myMax) {
return Math.floor(Math.random() * (myMax - myMin + 1)) + myMin;
}
parseInt
parseInt() 函式決議一個字串回傳一個整數,
如果字串中的第一個字符不能轉換為數字,則回傳 NaN,
function convertToInteger(str) {
return parseInt(str);
}
convertToInteger("56");
它還可以傳入第二個引數,指定了字串中數字的基數, 基數可以是 2 到 36 之間的整數,
parseInt(string, radix);
function convertToInteger(str) {
return parseInt(str, 2);
}
convertToInteger("10011");
數學計算方法 Arithmetic and calculus
- 冪運算:
Math.pow() - 開算術平方根:
Math.sqrt() - 開立方根:
Math.cbrt() - 取絕對值:
Math.abs() - 取對數:
Math.log()Math.log2()Math.log10() - 取最值:
Math.min()Math.max() - 三角(Trigonometric)計算:
Math.sin()Math.cos()Math.tan()
Math.pow(2,3)
8
Math.sqrt(4)
2
Math.cbrt(8)
2
Math.abs(-2)
2
Math.log(4)
1.3862943611198906
Math.log2(4)
2
Math.log10(100)
2
Math.log(2.7)
0.9932517730102834
Math.sin(4/5)
0.7173560908995228
Math.cos(4/5)
0.6967067093471654
Math.tan(4/5)
1.0296385570503641
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/551870.html
標籤:JavaScript
上一篇:前端配置化表單組件設計方法
下一篇:返回列表
