Try   HackMD
tags: Javascript 運算子 短路性質 可變與不可變 基礎語法

JavaScript 101 ─ 重點整理

在瀏覽器內執行 JS

  1. 新建 index.html 檔案。
  2. vim 編輯內容。
<script>  console.log(‘hello world’); </script>
  1. 回到 cmder ,直接打開 index.html,會直接瀏覽器打開。

在 CMI 編輯 JS 檔案

  1. 新建 index.js 檔案
  2. vim 編輯內容。
  3. 編輯:console.log(‘hello world’);
  4. 回到 cmder ,輸入 node index.js,即可看到內容出現在 CMI 上。

在 CMI 直接執行 JS

  1. 在 CMI 輸入 node,下一列會出現大於符號。
  2. 在大於符號旁輸入任何語法和運算,即可執行 JS。
  3. 若想要離開,可按 ^C,或者是輸入 .exit 即可離開跳出。

運算子

  1. 等於===
  2. 不等於 !==
  3. and &&
  4. or ||
  5. not !

範例:

let mood = 'sleepy'; let tirednessLevel = 6; if(mood === 'sleepy' || tirednessLevel > 8){    // TRUE console.log('time to sleep'); //所以顯示time to sleep } else { console.log('not bed time yet'); }

短路特性(邏輯運算)

  1. true false,回傳前值(因為到了第一個值就發現是 true)。所以像是 200 20,會回傳200。因為到了第一個就發現是true,就會馬上回傳第一個值。
  2. false true 回傳後值,因為需要看到最後。所以 0 22 回傳22。
  3. true && true 、true && false 都是回傳後值。因為要看到最後一個才會知道是 true 還是 false。所以像是 32 && 50 會回傳 50,22 && 0 會回傳 0。
  4. false && true 會回傳前值,因為第一個就發現是 false,就不需要接著看了。所以 0 && 22 會回傳 0。

二進位換算

  1. 運算方式:個位數是二的零次方乘以個位數的數字,十位數是二的一次方承以十位數的數字,百位數是二的二次方承以百位數的數字,以此類推。
  2. 舉例:101100
    = 2^5 * 1 + 2^4 * 0 + 2^3 *1 + 2^2 *1 +2^1 *0
    = 2^5 + 2^3 + 2^2
    = 32 + 8 + 4 = 44

位元運算

  1. <<:將位元往左移一位,可將其看成乘以 2 的幾次方。舉例來說:10 << 2 = 10 * 2^2 = 40、3 << 4 = 3 * 2^4 = 48。
  2. >>:將位元往右移一位,可將其看成除以 2 的幾次方。若不能整除會直接捨去。舉例來說:1024 >> 2 = 1024 / 2^2 = 256、57 >> 4 = 57 / 2^4 = 3 (直接捨去)
  3. &(and):
    1. 先將十進位的數字換算成是二進位的數字。10 & 15 = 1010 & 1111。
    2. 直立式運算。0 and 1 會變成0(0 是 false 1 是 true)、1 and 1 會變成 1,以此類推,1010 and 1111 = 1010。
    3. 將結果還原成十進位。1010就是10。
    4. 答案:10 & 15 = 10。(詳細解法如下圖)


4. |(or):

  1. 先將十進位的數字換算成是二進位的數字。10 | 15 = 1010 & 1111。
  2. 直立式運算。0 or 1 會變成1(0 是 false 1 是 true)、1 or 1 會變成 1,以此類推,1010 or 1111 = 1111。
  3. 將結果還原成十進位。1111 就是 15。
  4. 答案:10 | 15 = 15。(詳細解法如下圖)


5. ^(xor)(發音 exclusive or):

  1. 先將十進位的數字換算成是二進位的數字。10 ^ 15 = 1010 ^ 1111。
  2. 直立式運算。一樣的數字就會變成 0,不一樣的就會變成 1。1010 ^ 1111 = 0101。
  3. 將結果還原成十進位。0101 就是 5。
  4. 答案:10 ^ 15 = 5。(詳細解法如下圖)


6. ~(not):

  1. 先將十進位的數字換算成是二進位的數字。
  2. 1 變成 0、0 變成 1。
  3. ~15 = -16 ;~ 27 = -28

變數 Variable

  1. 名詞解釋
  • undefined:有宣告,但沒有賦予值。例如:var apple =
  • not defined:連宣告都沒有。
  1. 命名方式
  • 不可以用數字開頭(會出現 unexpected number):例如:var 123apple = 22。
  • 不可以用程式語言本身的功能字命名:例如:var var = 22
  • 命名有底線式跟駝峰式,基本上都以駝峰式為主。
    底線式如 var thank_you = “Thanks”。
    駝峰式如 var ThankYou = “Thanks”。
  1. a++ 與 ++a
  • 兩者的共同點:a++ 和 ++a 就是 a = a +1 也等於 a += 1。
  • 兩者的差別:
    a++ 會待整個列執行完後,才會再執行 a++。
var a = 0; console.log(a++ && 30) //顯示 0

因為它會看成 console.log ( a && 30 ),這列執行完,再看 a++。

++a 則是正常執行。

var a = 0; console.log(++a && 30) //顯示 30

因為此時就是單純執行 console.log( ++a && 30 )。

= 與 == 與 === 的意義及差別

  1. =: 一個等號的意思是賦值(宣告)。
  2. == 跟 === 皆判斷兩邊是否相等,但 === 會比 == 多比較兩邊的型態及多比較記憶體的位置。
console.log(0 == '0'); // true console.log(0 === '0'); // false,因為一邊是數字一邊是字串

字串 Object 中的等號

var obj = {a:1}; var obj2 = obj;

以上的兩行程式碼當中的記憶體位置會如下圖所示。

第一行像是我將 { a:1 } 存在某個記憶體位置(0x01),而 obj 內存放在這個記憶體位置(0x01)。
而第二行 obj2 變數不會再新增一個記憶體,他會直接導向 obj 的記憶體位置(0x01)。

那如果我更改 obj.a 這個物件呢?

var obj = {a:1}; var obj2 = obj; obj2.a = 2; console.log(obj === obj2) // true

以上的程式碼當中的記憶體位置會如下圖所示。

我們在第三行更改了 obj2.a 的值,按照剛剛的邏輯,他會更改記憶體位置(0x01)的內容,所以這時結果仍然是 true。

那如果我們另外新增一個物件,而非更改既有的呢?

var obj = {a:1}; var obj2 = obj; obj2.a = 2; obj2 = {b:1}; console.log(obj === obj2) // false

以上程式碼的記憶體位置如下圖。

此時就無法再更改記憶體位置(0x01)的內容了,因為這邊新增的是 {b:1},但在 0x01 裡面並沒有 b。所以這時後 obj2 就會另開一個記憶體位置(0x05),並在此放入 {b:1}。因此,結果才會是 false。

可變(mutable)與不可變(immutable)

觀念

  • 除了陣列跟物件是可變的外,其他都是不可變的(boolean, float, integer, string)
  • 重點是內容可不可變,而不是變數可不可變。

直接透過範例更了解可變與不可變的觀念。

不可變(immutable)範例 ─ 字串string

let fruit = 'apple'; fruit.split('') // 字串的的內容是不可變的,所以不可以在同一個記憶體位置內更改 fruit 的內容。 console.log(fruit); // apple

若要更改字串需重新賦值,如下。

let fruit = 'apple'; fruit = fruit.split('') // 將透過空格給切開的 fruit 重新找個記憶體位置儲存,一樣貼了 fruit 的標籤 console.log(fruit); // ['a', 'p', 'p', 'l', 'e']

可變(mutable)的範例 ─ 陣列(Array)

let fruit = ['apple', 'banana']; fruit.push('orange'); // 不需要另存記憶體,直接進行更改 console.log(fruit); // [ 'apple', 'banana', 'orange' ]

那如果我這時候將改變後的陣列另存記憶體呢?

let fruit = ['apple', 'banana']; fruit = fruit.push('orange'); console.log(fruit); // 3 // 這邊印出的是陣列的元素數(共 3 個)

為什麼這邊印出來的是 3 呢?

因為.push() 這個函式的回傳值是最新的陣列長度

所以當這時候我將這個函式的結果存到 fruit 裡的時候,就會將回傳值存進去,而這裡的回傳值是 3。

除此之外,要特別注意的是,某些陣列函式回傳值不是陣列,這時候就會需要另存記憶體。

let fruit = ['apple', 'banana', 'grape']; fruit = fruit.join('--'); //.join() 回傳值是 String,需另存 console.log(fruit); // apple--banana--grape // 印出的格式也是字串格式

條件句

If else

特性

  • if 條件句裡會判斷是否為 TRUE,如果是的話會執行,不是的話就會跑到 else / else if。
  • if 條件句內,數字不可為 0、字串不可是空的、不可以是未定義的變數、不可以是 null、不可以是 NaN(Not a Number)。

結構如下:

if (條件一) { 若條件一符合,執行此語句 } else if (條件二) { 若條件二符合,執行此語句 } else if (條件三) { 若條件三符合,執行此語句 ... } else { 若都沒有符合的,執行此語句 }

範例:

function testNum(a) { if (a > 0) { return "positive"; } else if (a = 0) { return "It's zero"; } else { return "NOT positive" } } console.log(testNum(-5)); // "NOT positive"

ternary operator 三元運算子

將 IF … ELSE… 條件句縮寫

縮寫結構:條件式 ? 對的話做這件事 : 不對的話做這件事;

let favoritePhrase = 'Love That!'; if (favoritePhrase === 'Love That!') { console.log('I love that!'); } else { console.log("I don't love that!"); }

以上是普通條件句寫法,以下使用三元運算子。

favoritePhrase === 'Love That!' ? console.log('I love that!') : console.log("I don't love that!");

Switch Case

除了一般的 ifelse ifelse 外,也可以使用 Switch Case 來執行條件句。

let athleteFinalPosition = 'first place'; switch(athleteFinalPosition) { case 'first place': // 代替 if console.log('You get the gold medal!'); break; // 如果 run 成功,break 用來防止繼續 run 到下一個 case 'second place': console.log('You get the silver medal!'); break; default: // 如果以上都不符合,那就 run 這個。 = else console.log('No medal awarded.'); break; }

陣列 Array

特性

  • 屬於物件型別,所以其屬於可變的,其相關的內建函式有些會改變原陣列,有些不會,也不一定都會回傳值
  • 儲存於變數時,實際儲存的是記憶體位置
  • 陣列內部可以再放入陣列

使用方式

存取性質相近(都是數字或是字串)、重複性高(可能有十幾個物件)。

var student_scores = []; student_scores[0] = 87; student_scores[1] = 27; student_scores[2] = 57; console.log(students_scores); //顯示 [87, 27, 57]

常用語法及內建函式

  • .length 計算陣列的物件數
var score = [23, 24, 64, 83, 14]; console.log(score.length); // 顯示 5
  • .length - 1 取得最後一個物件值
var score = [23, 24, 64, 83, 14]; console.log(score[score.length - 1]); // 顯示 14 //因為都是從 0 開始數,所以要記得減 1
  • .push() 在陣列末端加入值
var score = [23, 24, 64, 83, 14]; score.push(78); console.log(score); //顯示 [23, 24, 64, 83, 14, 78]
  • .join('') 將陣列中的元素結合變成字串
let sentence = ['a', 'b', 'c']; let newSen = sentence.join('!'); // 指定用!連結(如果不指定會直接結合) console.log(newSen); // 得’a!b!c’
  • .map(欲使用的函式) 將陣列套入函式
let sentence = [1, 3, 5]; function triple (x) { return x * 3 } console.log(sentence.map(triple)); // [3, 9, 15]

除此之外,.map() 可以累加使用,也可以使用匿名函式的方式。

let sentence = [1, 3, 5]; console.log(sentence .map(function (x) { return x * 3 }) .map(function (x) { return x * -2 }) ); // 最後得出 [-6, -18, -30]
  • .some(欲使用的函式):一樣也是將陣列套入函式

不一樣的地方是會回傳 boolean 值。如果是空陣列的話,會回傳 false。

const array = [1, 2, 3, 4, 5]; // 檢查是不是偶數 const even = (element) => element % 2 === 0; console.log(array.some(even)); // expected output: true
  • .filter(欲使用的函式) 將陣列套入函式

不同於.map()的地方在於:return 值可套用邏輯,回傳為 true 才會留下,false 會捨去。

let sentence = [1, 3, 5, 0, -2, -4]; console.log(sentence .map(function (x) { return x * 3 }) .filter(function (x) { return x >= 0 }) ); // [3, 9, 15, 0]

一開始先透過.map()套入 function,將元素全部乘以三後,再透過.filter(),過濾這些結果是否 >= 0。如果是的話,就會被回傳。所以這邊得到的是 [ 3, 9, 15, 0 ],-6 跟 -12 被捨棄了。

  • .slice(開始的索引值, 結束的索引值) 取得陣列中的某段元素,開始的索引值會被包含、結束的不被包含。

如果不寫結束的索引值,會預設 -1,也就是直接取到最後一個。

let sentence = [1, 3, 5, 0, -2, -4]; console.log(sentence.slice(1, 4)); // 得 [3, 5, 0]

開始的索引值 1 是 3,結束的索引值 4 是 -2,不過結束的索引值 -2 不包含。所以得 [3, 5, 0]。

  • .splice(開始刪除的索引值, 刪除幾個物件, 加入的物件) 陣列的刪除、插入或更改元素

單純刪掉物件,則不需要填入第三個參數(加入的物件)

如果再刪除幾個物件裡面填 0,就會是插入的功能。填 1 以上就會是更改的功能。

let sentence = [-1, 3, 5 , 7]; sentence.splice(1, 0, 2); console.log(sentence); // [-1, 2, 3, 5, 7]

如上,從索引值 1 (3)開始刪除,但是因為第二個填入的是 0,所以不刪除,變成在 3 之前插入了 2。所以得 [-1, 2, 3, 5, 7]。

let sentence = ['Jan', 'Jul', 'Dec', 'Apr', 'May']; sentence.splice(1, 2, 'Feb','Mar'); console.log(sentence); // ['Jan', 'Feb', 'Mar', 'Apr', 'May']

如上,從索引值 1 (‘Jul‘)開始刪除,第二個填的是 2,所以刪除了 ‘Jul‘ 跟 ‘Dec‘,再加入 ’Feb‘ 跟 ‘Mar‘。所以得出的結果是 ['Jan', 'Feb', 'Mar', 'Apr', 'May']。

  • .sort() 按照字母(a-z)或是數字(1-9)進行排序

按照開頭字母的順序及數字開頭的順序,並非按照數字大小

var months = ['March', 'Jan', 'Feb', 'Dec']; months.sort(); console.log(months); // ["Dec", "Feb", "Jan", "March"] var array1 = [1, 30, 4, 21, 100000]; array1.sort(); console.log(array1); // &nbsp;[1, 100000, 21, 30, 4]

如果希望陣列按照數字大小排序,由小排到大,可參考以下做法。

var arr = [1, 45, 100, 8]; arr.sort(function(a, b) { //可以先假設 a = 5 ,b = 1 方便比較 if (a === b) return 0 if (b > a) return -1 return 1 }); console.log(arr); //[1, 8, 45, 100]

如果想要由大排到小,只需要將 b > a 改成 a > b 即可,其他不變。

  • forEach() 將陣列內的每個元素,個個帶入函式中一次。

如果想要將陣列一個個印出、或是一個個套入函式中,不需要再寫迴圈,直接用forEach()即可。

var array1 = ['a', 'b', 'c']; array1.forEach(function(element) { console.log(element); }); // expected output: "a" // expected output: "b" // expected output: "c"
  • Array 名稱.indexOf('') 找出該 array 中某東西的索引值。
var fruits = ['apple', 'orange', 'grape']; fruits.indexOf('mango'); // -1 找不到 fruits.indexOf('grape'); // 2

物件 Objects

特性

  • 屬於物件型別,所以其屬於可變的
  • 儲存於變數時,實際儲存的是記憶體位置
  • 物件內部可以再放入物件或放入陣列

使用方式

在大括號{}內存放各種不同性質的物件。特性為資料存取方式容易,常透過.來連接欲存取資料。

var student = { Name: 'Peter', Score: '67', Phone: '023313, Address: 'Taipei city', father:{ //在物件內加入物件 Name: 'Nick', Phone: '02345' } }; console.log(student.father.Phone); // '02345'

也可透過中括號 [ ] 存取資料,但較不常見。

var student = { Name: 'Peter', Score: '67', Phone: '023313', Address: 'Taipei city', }; console.log(student['Name']); // 'Peter'

常用語法與內建函式

  • 新增物件內容
var student = []; var Peter = { Score: '67', Phone: '023313', } Peter.Address = 'Taipei city'; student.push(Peter); console.log(student); // [ { Score: '67', Phone: '023313', Address: 'Taipei city' } ]

直接透過 Peter.Address = 'Taipei city'; 新增物件的 Address 內容。

  • delete 刪除物件內容
var student = []; var Peter = { Score: '67', Phone: '023313', Address: 'Taipei city', } delete Peter.Score; console.log(student); // [ { Phone: '023313', Address: 'Taipei city' } ]
  • 將物件放入陣列中
var student = [ ] var Peter = { Name: 'Peter', Score: '67', Phone: '023313', Address: 'Taipei city', }; student.push(Peter); console.log(student[0].Score); // '67'

迴圈 Loop

DoWhile 迴圈

do while 迴圈有兩種用法。先假設我們想要印出 1 到 5。
第一種用法:

let i = 1; // 宣告變數 i 等於 1 do { // 啟動 do 迴圈 console.log(i); // 印出 i 值 i++ // 印完之後 i + 1 } while (i <= 5) // 如果 i <= 5 就繼續 do 迴圈 /* 1 2 3 4 5 */

第二種用法:

let i = 1; // 宣告變數 i 等於 1 do { // 啟動 do 迴圈 console.log(i); // 印出 i 值 i++ // 印完之後 i + 1 if (i > 5) { // 結束條件出現:如果 i 大於 5 break // 就跳出迴圈(如果 i 沒有大於五,就繼續迴圈) } } while (true) /* 1 2 3 4 5 */
  • break : 中斷,並跳出該 loop。
  • continue :一般來說如果迴圈搭配條件式使用,如果找到要找的值,就會停止繼續找剩下的了。continue 的用意就是即便找到了,繼續將剩餘的找完 (執行到 continue 的話,會跳過 continue 的下一行指令(依照以下範例的話是跳過 console.log('不是第' + i + '個,第' + i + '個是' + arr[i])),切換到 while 繼續執行)。

continue 範例:找出陣列中的值的索引值

var arr = [1, 5, 8, 12, 50, 99, 7, 20] var i = 0 do { i++ if ( arr[i] === 50 ) { console.log('抓到了 50 ! 他在第' + i + '個 !') continue } console.log('不是第' + i + '個,第' + i + '個是' + arr[i]) } while ( i < arr.length - 1 ) /*不是第1個,第1個為5 不是第2個,第2個為8 不是第3個,第3個為12 抓到了 50 ! 他在第4個 ! //一般來說沒有使用 continue 會只抓到這裡 不是第5個,第5個為99 //但是因為使用了 continue 所以繼續跑了 不是第6個,第6個為7 不是第7個,第7個為20 */

While 迴圈

目標:印出 1-5。

let i = 1; //初始值 i = 1 while (i <= 5) { // i <= 5 的時候執行以下內容(結束條件) console.log(i); // 將 i 印出 i++ } /* 1 2 3 4 5 */

簡單來說就是將剛剛的 do while 迴圈的 do 刪掉,將 while 的條件移到前面,其他不變。

For 迴圈

目標:印出 1-5。

for(i = 1; i <= 5; i++) { // for(初始值; 結束條件; 每圈結束要做的事) console.log(i); } /* 1 2 3 4 5 */

另一種 for 迴圈寫法,稱為 for...of

const array1 = ['a', 'b', 'c']; // 將陣列內的元素取名成 element for (const element of array1) { console.log(element); } // expected output: "a" // expected output: "b" // expected output: "c"

函式 Function

結構介紹

函式就有點像數學中的 f(x),所以這邊先以數學的 f(x) 為例。

f(a, b, c) = a + 2b + 3c
f(1, 2, 3) = 14
f(1, 1, 1) = 6

以下是程式中的函式。

function abc(a, b, c) { return a + 2 * b + 3 * c; // return + 藉由函式完成的內容  } console.log(function abc(2, 3, 4)); // 20

function 為函式。函式名稱:abc。參數:a, b, c。

注意事項

  • 回傳值為物件時,務必將大括號放置在 return 後,再接續放置物件。若是將大括號放在隔行,會顯示錯誤訊息(undefined)。範例如下。
function double(x) { return { // 大括號一定要放在這 answer: x * 2 } } console.log(double(5)); // { answer: 10 }
  • function 內可以可以再放 function
function print(anything) { // 有一個 print function anything(); // 填入的參數就是執行那個 function } function hello() { // 有一個 hello function console.log('hello'); // 印出 'hello' } print(hello) // 先呼叫 print function,再透過 print function 呼叫 hello function // 最後印出 hello
  • 傳值要小心,以下提供兩個範例。
function add(obj) { obj.number++ return 1 } let obj = { number: 10 } console.log(add(a)); // add funtion 回傳值是 1 // 1

兩個範例只差在最後的兩行。

上面的將 add function 直接放入 console.log() 裡,下面的先執行 add function 後,再印出 a。

這樣的小差別,卻可以讓兩個的答案完全不同。

function add(obj) { obj.number++ return 1 } let obj = { number: 10 } add(a) // 執行 add function,執行內容是將 a 這個物件的 number 的元素 + 1 console.log(a); // 經過剛剛執行後現在 a = 11 // 11

以陣列形式建構函式

目標:建構一個輸入 10 就會回傳 [1, 2, 3, 4,..10] 的陣列函式。

function generateArray(n) { var result = []; // 宣告一個空陣列 for (let i = 1; i <= n; i++) { result.push(i); // 將 i 值一個個放入 result 陣列中 } return result } console.log(generateArray(5)); // [ 1, 2, 3, 4, 5 ]

陣列型式也可與 function 內可結合 function 的功能結合,如下:

function transform(arr, transformFunction) { var result = []; for(let i = 0; i < arr.length; i++) { result.push(transformFunction(arr[i])); } // 將 arr 的值一個個帶入函式後的結果放入 result 陣列中 return result } function double(x) { return x * 2 } console.log( transform([1, 3, 5], double) ); // [ 2, 6, 10 ]

宣告函式的其他方法

我們先來看一般宣告函式的方法。

function triple(x) { return x * 3 }

宣告一變數 = 函式

如標題,先宣告一個變數,再將此變數賦值給一個函式。

let triple = function(x) { return x * 3 }

匿名函式 Anonymous Function

顧名思義,匿名函式就是沒有名字的函式。會直接將名字省略,所以通常在使用此函式時不需要先寫一個函式、應用時套用參數,欲使用時直接將整個函式寫出來即可。

// let triple = function(x) { // return x * 3 // } // 不需要像以上寫出函式 function accar(arr, accarFunc) { newArr = []; for (let i = 0; i < arr.length; i++) { newArr.push(accarFunc(arr[i])); } return newArr; } console.log( accar([2, 4, 6], function(x) { // 這裡就是匿名函式 return x * 3 //直接寫下函式內容即可 }) // 這樣的函式功能與前三行被備註掉的函式功能一樣 ); // [ 6, 12, 18 ]

參數(parameter)和引數(argument)

什麼是參數跟引數呢?看個範例就知道了。

function add(a, b) { return a + b; } const c = 10; const d = 20; add(c, d);

參數是範例中的 a 跟 b。引數是實際案例中的 c (10)跟 d(20)。

引數(argument)跟 array 很像,是個類陣列 (array-like) 的物件,可被放入 function 內。

function PrintArgu(a, b) { console.log(arguments); } PrintArgu(3, 4, 5); // [Arguments] { '0': 3, '1': 4, '2': 5 }

依照上面的這個範例,我們可以看出來 arguments 確實是個類陣列的物件。因此我們可以透過這個特性,去做相關利用。

function PrintArgu(a, b) { console.log(arguments[1]); // 取 arguments 索引值 1 的內容 } PrintArgu(3, 4, 5); // 4

常用內建函式

數字相關

  • Number() 將字串轉換為數值
var a = 10; var b = '20'; console.log(a + Number(b)); // 30
  • .toString() 將數值轉換成字串
var a = 10; let b = '50'; console.log(a.toString() + b); // 1050
  • parseInt(參數,幾進位的參數) 將字串轉換成整數

若沒寫第二個參數預設十進位

var a = 10; var b = '20'; console.log(a + parseInt(b)); // 30
  • parseFloat(參數) 將字串轉換為小數
var a = 10; var b = '20.26'; console.log(a + parseFloat(b)); // 30.26
  • .toFixed(到小數第幾位) 將小數點捨去到指定的位數

剩餘的小數點會自動四捨五入

var a = 10; var b = '20.268352'; console.log(parseFloat(b).toFixed(3)); // 20.268(後面的會四捨五入)

若是不填參數預設全部捨去

var a = 10; var b = '20.268352'; console.log(parseFloat(b).toFixed()); // 20
  • Number.MAX_VALUE 列出記憶體可儲存的最大數值
console.log(Number.MAX_VALUE); // 會出現1.7976931348623157e+308 // 代表數字最多可到三百多位,一旦超過這個位數計算就會不精準
  • Number.MIN_VALUE 列出記憶體可儲存的最小數值
console.log(Number.MAX_VALUE); //會出現5e-324 // 代表數字最多可到小數點後三百多位,一旦超過這個位數計算就會不精準
  • Math.PI 印出常數 π

PI 是常數(constant),固定不會變的值,通常以大寫表示

console.log(Math.PI); // 3.141592653589793 console.log(Math.PI.toFixed(4)); // 3.1416
  • Math.ceil() 小數點無條件進位成整數
console.log(Math.ceil(12.35)); // 13
  • Math.floor() 小數點無條件捨去成整數
console.log(Math.floor(12.35)); // 12
  • Math.round() 小數點四捨五入成整數
console.log(Math.round(12.35)); // 12 console.log(Math.round(12.55)); // 13
  • Math.sqrt() 開根號
console.log(Math.sqrt(16)); // 4 console.log(Math.sqrt(20)); // 4.47213595499958
  • Math.max(可放多個參數) 取最大值
console.log(Math.max(1, 3, -5)); // 3
  • Math.min(可放多個參數) 取最小值
console.log(Math.min(-1, 10, -2)); // -2
  • Math.pow(參數, 的幾次方) 取參數的幾次方
console.log(Math.pow(2, 5)); // 32
  • Math.random() 隨機取得 0 到小於 1 之間的數(也就是 0 - 0.999…)
console.log(Math.random()); // 0.3747946876975716 console.log(Math.random() * 10); // 3.7667189027459913

那如果我們想要用此語法製作出隨機選出 1 - 10 的數呢? 或許我們可以套用之前學的無條件捨去 ─ Math.floor()

console.log(Math.floor(Math.random() * 10)); // 0 // 因為也是有可能隨機選到 0.000...的值,即便 * 10 還是 0 console.log(Math.floor(Math.random() * 10 + 1)); // 2 // 所以可以全數 + 1,解決此問題

透過此語法也可以自己定義出隨機選值的範圍。

字串相關

  • .toUpperCase() 全數轉成大寫
var a = 'aBc'.toUpperCase(); console.log(a); // ABC
  • .toLowerCase() 全數轉成小寫
var a = 'AbC'.toLowerCase(); console.log(a); // abc
  • .charCodeAt(字串索引) 可得字母的數字值
var alphbat = 'ABC'; console.log(alphabat.charCodeAt(1)); // 66 (得出大寫 B 的 CharCode 是66)
  • String.fromCharCode() 從數值轉換成字母
var str = String.fromCharCode(66, 98, 75); console.log(str); // BbK

charCode 字母大寫跟小寫都會差 32,小寫比大寫大,像剛剛 B 是 66,小寫 B = 66 + 32 = 98。可以利用這個固定差取得大寫字母或小寫字母。

var a = 'Pat';  // 先宣告一個變數 var aCode = a.charCodeAt(1); // 取出'a'的數值 var str = String.fromCharCode(aCode - 32); // 將 a 的數值 - 32 = 大寫,再將此值轉成字母並存入str console.log(str); // 得出 A
  • .indexOf(要找的東西) 得出要找的東西的索引。
var greeting = 'My name is Valen. Nice to meet you!'; var aCode = greeting.indexOf('is'); console.log(aCode); // 8

那如果沒找到呢? 會回傳 -1。

var greeting = 'My name is Valen. Nice to meet you!'; var aCode = greeting.indexOf('he'); console.log(aCode); // -1 //不存在的東西都會是 -1

這個特性可以搭配條件式使用,如果 >= 0 等於存在,如果 <0 等於不存在。

let sentence = 'Hello! Nice to meet you.'; if (sentence.indexOf('he') >= 0) { console.log('"he" is existed.') } else { console.log('"he" is not existed.') } // "he" is not existed.
  • .replace(被取代的字串, 新的欲放入的字串) 取代字串

只會取代一次

let sentence = 'Hello nice to meet you.'; let newSen = sentence.replace('e', 'i'); // 將 e 改成 i console.log(newSen); // Hillo nice to meet you. // 只取代了 hello 的 e,nice 的 e 並沒有取代

那該如何取代多個呢?/ 被取代的字串/g (global)

let sentence = 'Hello nice to meet you.'; let newSen = sentence.replace(/e/g, 'i'); //將所有的e改成i console.log(newSen); // 得Hillo nici to miit you.
  • .trim() 將前後空格去掉
let sentence = ' Hello nice to meet you. '; let newSen = sentence.trim(); console.log(newSen); // Hello nice to meet you.
  • .split(以此切開的字串) 將字串切開並放入陣列
let sentence = 'Hello nice to meet you.'; let newSen = sentence.split(' '); //以空格來切 console.log(newSen); // [ 'Hello', 'nice', 'to', 'meet', 'you.' ]

◎ 讀取 csv 格式時,很常是以逗號分割,如 data1, data2, data3 等等,這時就可以使用。若前後有空格,可搭配.trim()使用

  • .length 得總共有幾個字(包含空格或符號)
let sentence = 'Hello nice to meet you.'; let newSen = sentence.length; console.log(newSen); // 23(包含括號及句號總共 23 個字)

Debugger

碰到 bug 的時候可以透過瀏覽器的 debugger 一行行的將程式碼跑過,透過視覺化的方式了解跑程式的過程。

環境

必須在 Chrome 中使用。可先在 cmder 建立一個 html 檔案,並透過 vim 編輯後從 Chrome 打開。以下提供範例內容。

<Script> debugger //在想要透過 debugger 跑的地方前輸入 debugger var i = 1; do { console.log(i); i++ } while(i <= 5); </Script>

在 Chrome 中打開 dev tools 後點開 Sources 標籤,重新整理就會看到游標跑在 debugger 上。以下為圖示。

  1. console:在 debugger 過程中可隨時切換至 console 確認進度。
  2. 暫停與繼續執行鍵。
  3. 開始 debugger 功能。
  4. 輸入想確認的值。像是在此可輸入 i。