圖說演算法使用JavaScript(三)

3-4題目:最常出現的字母
撰寫一個函數,傳入引數為一個字串,其輸出的結果會將該字串中出現頻率最高的字母輸出。

JS     max_character.htm

const my_max = str =>{
	const words = {};  //You can create a const object

	for (let ch of str)
		words[ch] = words[ch]+1 || 1;

	let counter = 0;
	let most = null;

	for (let ch in words) {
		if (words[ch] > counter){
			counter = words[ch];
			most = ch;
		}
	}
	return most;
};
console.log(my_max("tomorrow"));

PHP    max_character.php

//$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$my_str="Hello World! 你好世界!";
//$my_str="我為人人,人人為我";
//$my_str="gooddoog";
echo "原來的字串:".$my_str."<br>";

function mb_str_split($str){
	//不分中英字串都可以切成陣列
	return preg_split('/(?<!^)(?!$)/u',$str);
}

function get_most_str($str){

	$arr = mb_str_split($str);    //切字串成陣列
	$len = count ($arr);
	$my_count = 0;
	
	for ($i=0 ; $i<=$len-1; $i++){
		
		$str_count=substr_count($str,$arr[$i]);
		//計算出現次數
		if ($str_count>$my_count){

			$my_count=$str_count;
			$most = $arr[$i];
		}
	}

	return [$most,$my_count];
}

$most_str= get_most_str($my_str);
echo "最大數為".$most_str[0]."=".$most_str[1]."<br>";
使用函數:
substr_count() 計算子字串在字串中出現的次數
3-5題目:判斷兩字是否相同 Anagrams
這個函數的功能是給定兩個包含相同數量的字母的單字或片語,並進行判斷所傳入的單字或片語是否相同的檢查函數。

JS   anagrams.js

const  compare = str =>{

	const table ={}; //宣告一個table物件

	for (let char of str.replace(/\w/g, "").toLowerCase())
		table[char] = table[char]+1 || 1;

	return table;
};

const anagrams = (strA, strB) =>{
	const charA = compare(strA);
	const charB = compare(strB);

	if (Object.keys(charA).length !==Object.keys(charB).length)
		return false;

	for (let char in charA)
		if (charA[char] !== charB[char]) return false;

	return true;
};

console.log(anagrams("happy birthday", "happy birthday"));
console.log(anagrams("happyy birthday", "hhappy birthday"));
說明:
str.replace(/\w/g,"").toLowerCase();
\w 包含數字字母與底線,等同於[A-Za-z0-9_]      出處

PHP     anagrams.php

$my_str_1="happy birthday";
//$my_str_1="大家好";
$my_str_2="hhhappybirthday";
//$my_str_2="happy birthday";

echo "字串_1:".$my_str_1."<br>";
echo "字串_2:".$my_str_2."<br>";

function mb_str_split($str){
	//不分中英字串都可以切成陣列
	return preg_split('/(?<!^)(?!$)/u',$str);
}

/*
$str_1_ar = mb_str_split($my_str_1);
$str_2_ar = mb_str_split($my_str_2);

$str_len_1 = count ($str_1_ar);
$str_len_2 = count ($str_2_ar);
$flag =($str_len_1 != $str_len_2) ;	
$i=0;
if($flag==1){
	echo "這兩個長度不同<br>";

}else{
	
  while ($i<= $str_len_1-1){

  		$flag2=strcmp($str_1_ar[$i],$str_2_ar[$i]);
	    
	    if($flag2==1){
	    	echo "這兩個字母不同<br>";
	    	break;
	    }
	      $i++;
	}
}
*/
function my_anagrams ($str1, $str2){

	$str_1_ar = mb_str_split($str1);
  $str_2_ar = mb_str_split($str2);
  $str_len_1 = count ($str_1_ar);
  $str_len_2 = count ($str_2_ar);
  $flag1 =($str_len_1 != $str_len_2) ;
  $i=0;	
  $msg1="這兩個長度相同<br>";
  $msg2="這兩個字母相同<br>";

  if($flag1==1){
	  $msg1="這兩個長度不同<br>";
	  $msg2="這兩個字母不同<br>";
  }
  else{
  	 while ($i<= $str_len_1-1){

  		$flag2=strcmp($str_1_ar[$i],$str_2_ar[$i]);
	    
	    if($flag2==1){
	    	$msg2="這兩個字母不同<br>";
	    }
	      $i++;
		}//while
   
  }//elseif
	
  return [$msg1,$msg2];

}//function

$my_msg = my_anagrams($my_str_1,$my_str_2);

echo $my_msg[0];
echo $my_msg[1];
函數使用:
strcmp(str1,str2) 比較兩個字串(對大小寫敏感)
3-6題目:反向陣列  Reverse Array
將給定的陣列中的元素,由前往後排列方式,變更成由後往前的排列順序。例如給定原陣列的內容值為[1,2,3,4],則所撰寫的這個函數會回傳[4,3,2,1]‵.

JS      reverse.js

const rev1 = dim =>{
	for (let i=0; i <dim.length /2; i++){
		const temp = dim[i];
		dim[i] = dim[dim.length-1-i];
		dim[dim.length-1-i]=temp;
	}
	return dim;
};

const rev2 = dim =>{
	for (let i=0; i<dim.length/2; i++) {
		[dim[i], dim[dim.length-1-i]] = [
			dim[dim.length-1-i], dim[i]
		];
	}
	return dim;
};

console.log("['a','e','i','o','u']反向陣列:",rev1(['a','e','i','o','u']));
console.log("[2,4,6,8,10]反向陣列:",rev2([2,4,6,8,10]));

PHPh      reverse.php

$my_arr_1=array("a","e","i","o","u");
$my_arr_2=array(2,4,6,8,10);
//$my_str_2="happy birthday";

echo "陣列_1:";
print_r($my_arr_1);
echo "<br>";
echo "陣列_2:";
print_r($my_arr_2);

$re_arr_1 = array_reverse($my_arr_1);
$re_arr_2 = array_reverse($my_arr_2);

echo "<br>";
echo "反陣列_1:";
print_r($re_arr_1);
echo "<br>";
echo "反陣列_2:";
print_r($re_arr_2);
函數使用:
array_reverse($arr) 以相反的順序傳回數組

圖說演算法使用JavaScript(二)

3-1題目:字串反轉(String Reversal)
撰寫一個函數,傳入的引數為一個字串,其輸出結果會將該字串以反轉的方式輸出。

JS   String_Reversal.js

const reverse1 = str =>
	str
		.split("")
		.reverse()
		.join("")

const reverse2 = str =>{
	let result = "";
	for (let ch of str) result = ch +result;
		return result;
	};

console.log(reverse1("不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。"));
console.log(reverse2("一個人年輕的時候,不會思索,他將一事無成。"))

PHP    String_Reversal.php

$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
echo "原來的字串:".$my_str."<br>";

function my_reverse ($str){

	$len = strlen($str);
	$str_ar = str_split($str);
	$str_ar = array_reverse($str_ar);
	$str_ar = join($str_ar);
	//echo $len;
	return $str_ar;

}

$my_len=my_reverse($my_str); 
$my_len = strrev($my_str);
//這兩個方法,中文反轉後都會出現亂碼。
使用函數
strlen($str) 傳回字串的長度
array_reverse($arr) 以相反的順序傳回陣列
join() 把陣列組合為一個字串
strrev 反轉字串

PHP 中文字串反轉會出現亂碼,需要做以下的判斷。


3-2題目:迴文Palindrome
所謂迴文是指由左唸到右或由又唸到左,字母排列順序都一樣的,例如以下的字串就是一個迴文:
"人人愛我!我愛人人"

JS   palindrome.js

const isPalindrome = str =>
	str
        .split("")
	.every((ch,index) => ch === str[str.length - 1 - index]);

console.log("[人人愛我!我愛人人] 這句話是否為迴文(palindrome)?",
             isPalindrome("人人愛我!我愛人人"));

PHP   palindrome.php

$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
//$my_str="Hello World! 你好世界!";
//$my_str="我為人人,人人為我";
//$my_str="gooddoog";
echo "原來的字串:".$my_str."<br>";

function mb_str_split($str){
	//不分中英字串都可以切成陣列
	return preg_split('/(?<!^)(?!$)/u',$str);
}

$arr = mb_str_split($my_str);
print_r ($arr);
$len = count($arr);     //計算字串數
$mid_len=floor($len/2); //取中間整數
echo "<br>-----<br>";

for ($i=0; $i<=$mid_len-1; $i++){

	 if($i==0) 
	 	$last=$len-1;   //第一筆 頭-尾
	 else 
	   $last=$len-1-$i;
	//比對兩個字是否一樣,一樣就為0
	$check_f = strcmp($arr[$i],$arr[$last]); 
	echo $arr[$i]."-".$arr[$last]."<br>";
	if ($check_f ==0){
		$flag="true";
		continue;
	}else{
		$flag="false";
		//break;
	}
}

echo "<br>".$len."-".$mid_len."<br>";
echo "FLAG=".$flag;
?>
使用函數:
count() 傳回陣列中元素的數目
floor() 取中間整數
strcmp 比較兩個字串(對大小寫敏感)

3-3題目:整數反轉(Integer Reversal)
整數反轉的函數是只給定一個整數的引數,該函數會反轉該數字的順序。例如,原傳入字串為「12345」,則其輸入結果為「54321」。

JS      inter_reversal.js

const rev = integer =>
	Math.sign(integer)*parseInt(
		integer
		.toString()
		.split("")
		.reverse()
		.join("")
		);
console.log(rev(98754321));
console.log(rev(-987001200));

PHP    integer_reversal.php

$my_int=-987001200;
//$my_int=987654321;
//print_r(str_split($my_int));
echo "原始的數字=".$my_int;
function integer_reversal ($int){
    $minus=0;
	$arr=str_split(strval($int));
		
	$len = count($arr)-1;
    //echo "<br>".$len;
	for($i=$len; $i>=0; $i--){
		if($arr[$i]=="-")
		 $minus=1;  //偵測是否為負數
		else
      	 $re_arr[]=$arr[$i];
    }
	return [$re_arr,$minus]; //返回兩個數值
}

$my_re=integer_reversal($my_int);
echo "<br>";
$num=intval(join($my_re[0]));
if ($my_re[1]==1)
$num=$num*(-1);	
echo "<br>反轉後數字=".$num;
使用函數:
strval() 函數用於取得變數的字串值

PHP如何正確計算中文字串的長度

  在PHP程式設計中,我們常常遇到需要計算字串長度的場景。一般情況下,我們習慣用 strlen() 函數或 mb_strlen() 函數來計算字串長度。然而,在處理中文字串時,我們會發現使用 strlen() 函數會出現問題,因為中文字元不按照一般的字元計算方式來計算長度。那麼在PHP中,如何才能正確計算中文字串的長度呢?下面就來探討一下相關的問題。
一、PHP中字串長度的計算方式
在PHP中,計算字串長度的方式有兩種,一種是簡單的字元計數,另一種是按照實際字元長度計算。在計算字串長度時,我們會遇到兩種情況:
1.ASCII字元:在計算ASCII字元的長度時,直接使用 strlen() 函數即可。
2.中文字元:中文字元在Unicode佔用兩個字節,而在GBK中佔用兩個位元組或三個位元組。在計算中文字元長度時,需要按照字元的實際長度來計算。

二、誤用strlen() 函數的問題
strlen() 函數是PHP中一個用來計算字串長度的基本函數,它可以傳回指定字串的長度。然而,在處理中文字串時,使用 strlen() 函數會出現問題,計算長度不準確。這是由於 PHP 預設採用 ASCII 編碼,而對於 Unicode 編碼的中文字符,一個字元被解析成多個字節,導致計算長度時發生錯誤。

三、解決問題的方法
既然 strlen() 函數無法正常計算中文字元的長度,那麼我們該如何計算中文字元的長度呢?以下就是三種常用的解決方案:

1.使用 mb_strlen() 函數
PHP提供了 mb_strlen() 函數來解決字串長度問題。 mb_strlen() 函數是一個多位元組字串長度函數,它可以傳回字串的實際長度,包括中文字元在內。使用mb_strlen() 函數計算中文字串的長度時,需要傳入第二個參數來指定字元編碼,例如:
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$len=mb_strlen($my_str,'utf-8'); // len=27

2.使用iconv_strlen()函數
iconv_strlen() 函數可以用來計算字串的長度,它也可以正確處理中文字串的長度。 iconv_strlen() 函數結構類似strlen() 函數,只不過在計算長度時需要傳入第二個參數指定字元編碼,例如:
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$len=iconv_strlen($my_str,'utf-8'); // len=27

3.計算位元組數再除以2 或3
除了使用PHP自帶的函數來處理之外,我們還可以透過計算中文字元的位元組數來解決長度計算問題。

把中文英文字串切成陣列-通用的方法

function mb_str_split($str){
	
	return preg_split('/(?<!^)(?!$)/u',$str);
}

圖說演算法使用JavaScript(一)

演算法特性內容與說明
輸入 Input0個或多個輸入資料,這些輸入必須有清楚的描述或定義。
輸出 Output至少會有一個輸出’結果,不可以沒有輸出結果。
明確性 Definiteness每一個指令會步驟必須是簡潔明確而不含糊的。
有限性 Finiteness在有限步驟後一定會結束,不會產生無窮迴路。
有效性 Effectiveness步驟清楚且可行,能讓使用者用紙筆計算而求出答案。
執行Node.js
再命令提示字元下輸入Node即可執行。

地球上最常見經典演算法

分治演算法

分治法Divide and conquer是一種很重要的演算法,我們可以應用分治法來逐一拆解複雜的問題,核心精神是將一個難以解決的大問題依照不同的概念,分割成兩個或更多的子問題,以便各個擊破,分而治之。
範例:  
如果有8張很難畫的圖,我們可以分成2組各四幅來完成,如果還是覺得太複雜,繼續再分成四組,每組各兩幅來完成,利用相同模式反覆切割問題,這就是最簡單的分治法核心精神。

遞迴演算法

遞迴是種很特殊的演算法,分治法和遞迴法很像,都是將一個複雜的演算法問題的規模變得越來越小,最終使子問題容易求解。
從程式語言的角度來說,遞迴的定義是,假如一個函數或副程式,是由自身所定義或呼叫,就稱為遞迴Recursion,它至少要定義2種條件,一個可以反覆執行的遞迴過程,與一個跳出執行過程的出口。
範例: recursion.js,recursion.php
我們知道階乘函數是數學上有名的函數,對遞迴式而言,也可以看成是很典型的範例,我們一般以符號"!"來表示階乘。如4階乘可寫為4!。
n!=n*(n-1)*(n-2).....*1

JS 範例    recursion.htm

let i=5;
		//var ans;
		function factorial(i) {
			var ans;
			if (i==0) return 1
			else ans=i*factorial(i-1);
			return ans;
		}


	console.log(`${i}階乘值為`+factorial(i));

PHP   範例        recursion.php

<?php
$count_num=5;

function factorial($i){

	if ($i==0) {
		$ans=1;
	}
	else{
		$ans=$i*factorial($i-1);
	}
    return $ans;
}

$result=factorial($count_num);
echo "count_num".$result;
?>

貪心法(給我最好,其餘免談)

貪心法Greed Method又稱為貪婪演算法,分法是從某一起點開始,在每一個解決問題步驟使用貪心原則,都採取在當前狀態下最有利或最優化的選擇,不斷的改進該解答,持續在每一步驟中選擇最佳的方法,並且逐步逼近給並的目標,當達到某一步驟不能再繼續前進時,演算法停止,以盡可能快的求得共好的解。

動態規劃演算表(分治法的麻吉兄弟)

動態規劃法Dynamic Programming Algorithm ,DPA 類似分治法,由20世紀50年代初美國數學家R.E.Bellman所發明,用來研究多階段決策過程的優化過程與求得一個問題的最佳解。動態規劃法主要的做法是如果一個問題答案與子問題
相關的話,就能將大問題拆解成各個小問題,其中與分治法最大不同的地方是可以讓每一個子問題的答案被儲存起來,以供下次求解時直接取用。這樣的作法不但能減少再次需要計算的時間,並將這些解組合成大問題的解答,故使用動態規劃則可以解決重複計算的缺點。

疊代演算法(不斷繞圈的演算法)

疊代法iterative method 是無法使用一次求解,而須反覆運算,例如用迴圈去循環重複程式碼的某些部份來得到答案。
fac.js;fac.php > 請利用for迴圈設計一個計算1!~n!的遞迴程式

fac.js => 不能執行因為我的環境沒有安裝prompt套件

PHP 範例       fac.php

<?
$fac = 1;
$my_n = 10;
for ($i=0; $i<=$my_n; $i++){

	for ($j=$i; $j>0; $j--){
		$fac *=$j;     // $fac=$fac*$j
	} 
	echo $i."!=".$fac."<br>";
	$fac = 1;   //$fac要歸1
}
?>

While迴圈  需要具備三個條件

1.變數初始值
2.迴圈條件式
3.調整變數增減值
<?php
$i = 1;                   //變數初始值
while ($i<10){            //迴圈條件式
	echo $i."<br>";
    	$i +=1;           //調整變數增減值
}   
?>

枚舉演算法(人人都有份的演算法) Enumerate

枚舉法(又稱窮舉法),是一種常見的數學方法,也是日常中使用到最多的一個演算法,它的核心思想就是:枚舉所有的可能。根據問題要求,一一枚舉問題的解答,或者為了解決問題而分為不重複、不遺漏的有限種情況,一一枚舉並加以解決,最終達到解決整個問題的目的。枚舉法這種分析問題、解決問題的方法,得到的結果總是正確,唯一的缺點就是速度太慢。
範例:
當某數1000,依次減去1,2,3...直到哪一數時,相減的結果開始為負數。

JS enumerate.js

<script type="text/javascript">
		x=1;
		num=1000;
		while (num >=0){
			num-=x;
			x=x+1;
		}

		console.log(x-1);
</script>

PHP       enumerate.php

$x=1;

$my_num=1000;
$j = $my_num;
while ($j >=0){

	$j -=$x;
	$x = $x+1;
}

$y=$x-1;
echo $my_num."減到數字".$y."會開始是負數";

波蘭麵種(Poolish)麵包

參考資料

波蘭種(Poolish)=液種
澎澎地如同海綿般的質地,
含水量高, 也可稱之為液種

先製作波蘭種|比例 1:1:0.2

從預計使用的總麵粉量,先取出約30%
以麵粉:水:速發酵母
=1:1:0.2 的比例製作
p.s. 因為長時間發酵,
速發酵母甚至可用更低比例(0.08~0.1%)製作
也可依照當天氣溫調整使用量
極少用量的速酵就足夠了唷!
B. 主麵團:
麵粉=500-150=350g
水=350-150=200g
速發酵母=5-0.3=4.7g
鹽巴=9g

波蘭種發酵|常溫or冷藏

可選擇以下兩種方式進行發酵:
<1> 當日常溫發酵法:
室溫25~27℃, 發酵約8~10個小時
<2> 隔夜冷藏發酵法:
在室溫26℃左右發酵1~2小時後放入冰箱4℃冷藏室繼續冷藏發酵約12~17小時
20250216第一次做歐式麵包
烘烤:
溫度215度烤30分鐘
20250218
烘烤:
加蓋子、蒸氣200度烤30分鐘、再開蓋215度烤20分鐘

JavaScript 精選14堂課(五)

文件物件模型DOM
DOM是一個階層的樹狀結構,就像目錄關係一樣,一個根目錄下會有子目錄,子目錄下還包括另一個子目錄,每一個物件都稱為一個節點。
舉例來說,瀏覽器最上層的節點是window,也就是根結點root,接下來是HTML文本文件本身doucument,而HTML文件的組成是HTML標記,<html>文件標記的下一層是<body>標記,因此<body>標記就是<html>標記的子節點,當我們在JavaScript語法裡要參考<body>標籤,就可以表示:
  window.document.body

範例:取得網頁元件

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>取得元件</title>
	<style>
	*{
		font-size:20px;
		font-family: Microsoft JhengHei;
	}
	</style>
	<script>
	function chgBorder(){
		document.getElementById('myImg').border="5";
		document.getElementById('myImg').style.borderStyle="double";

	}
	function chgColor(){
		document.getElementsByTagName('p')[0].style.cssText = "color:blue;font-size:25px;";
	}
	</script>
</head>
<body>
	<p>您好</p>
	<p>很高興認識您!</p>
	<!--圖片-->
	<img id="myImg" src="17.jpg" boder="0" width="200">
	<br>
	<!--按鈕-->
	<input type = "button" onclick="chgBorder()" value ="圖片加框線">
	<input type = "button" onclick="chgColor()" value ="改變字體顏色">

	
</body>
</html>
範例中使用了document.getElementById('myImg')表示取得id名稱為myImg的原件,也就是<img>物件;document.getElementsByTagName('p')[1]表示取得標記為<p>的物件,其中[1]是索引值,從0開始,因此[1]表示取得第2個<p>物件。
修改物件CSS的樣式必須透過HTMLElement.style屬性,它會傳回CSSStyleDeclration物件,使用方式如下:

範例:處理物件節點

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>NodeList</title>
	<style>
	*{
		font-size:20px;
		font-family: Microsoft JhengHei;
	}
	div{
		color:red;
		border:1px solid red;
		width:500px;
		padding:10px;
		text-align:center
	}
	</style>
	<script>
	function check(){
		let result = document.getElementById("result");
		let d1 = document.getElementById("div1");
		
		result.value = "第一個子節點(firstChild)的nodeValue = "+
		d1.firstChild.nodeValue +"\n";

		result.value +="第一個子節點(childNodes)的nodeValue= "+
		d1.childNodes.item(0).nodeValue+"\n";

		result.value +="最後一個子節點(lastChild)的nodeType ="+
		d1.lastChild.nodeType+"\n";

		result.value +="div1 物件下一個的節點(nextSibling) = "+
		d1.firstChild.nextSibling.getAttribute("id")+"\n";

		result.value +="a1的父節點(parentNode) = "+document.getElementById
		("a1").parentNode.getAttribute("id");
	}
	</script>
</head>
<body>
	
	<input type = "button" onclick="check()" value ="檢查節點關係"><br>
	<textarea cols="50" rows="9" id="result"></textarea>
	<div id="div1"> Coffee
	<a href="#" id="a1">這是a1</a>
	<a href="#" id="a2">這是a2</a>
	<a href="#" id="a3">這是a3</a>
	</div>
</body>
</html>
DOM物件模型可以將HMTL文件視為樹狀結構,利用下表屬性,就可以走訪和處理樹狀結構中的節點。
屬性說明
firstChild第一個子節點
parentNode走訪母節點
childNodes走訪子節點
previousSibling走訪上一個節點
nextSibling走訪下一個節點
走訪節點時,可以取得節點的名稱、內容及物件的種類,如下表所示:
屬性說明
nodeName名稱
nodeValue內容
nodeType種類
nodeType為取得物件種類,1表示元素節點、3表示文字節點。

JavaScript 精選14堂課(四)

自訂函式

使用函式Function有下列優點:
1.可重複叫用,簡化程式流程。
2.程式除錯容易。
3.便於分工合作完成函式。

格式:
function 函式名稱 ()
{
程式敘述;
return 回傳值
}

函式宣告式(Function Declaration)

<script type="text/javascript">
	
	myfunc(10, 20);     //呼叫放在函式前
	function myfunc(a, b){
		console.log('a='+a+',b='+b);
	}
	myfunc(100,200);    //呼叫放在函式後
</script>

呼叫函式方法不管放在函式定義之前或之後都可以,很方便就能夠重複使用。


函式表達式Function Expressions

格式:
var 變數 = function [函式名稱](參數1,參數2,...,參數n){
程式敘述;
return 回傳值;
};
<script type="text/javascript">
	
	function checkflag(flag){
		if(flag) {
			var myfunc = function(a,b){
				return a + "+" + b +"=" + (a+b);
			};
		}else{
			var myfunc = function(a,b){
				return a + "*" + b + "=" + (a*b);
			};
		}
		console.log(myfunc(10,20));
	}

	checkflag(true);
	checkflag(false);
 </script>

以下函式為本身呼叫自己的模式稱為「遞迴呼叫」Recursive Calls。使用遞迴函式可以讓程式碼變得簡潔,正確使用有助於提升執行效率,但是使用時要特別注意遞迴的結束條件,否則會造成無窮迴圈。
<script type="text/javascript">
	
	var myfunc = function factorial(n){
		let x = (n ==1 ? n : n * factorial(n-1));
		console.log(n + ">" + x)
		return x;
	};

	console.log("5!=" + myfunc(5));
</script>

箭頭函式  Arrow function 一種函式精簡的寫法

格式:
(參數) => {
程式敘述;
return value;
}
var myFunc = function(a,b){
    return a+b;
}
console.log(myFunc(10,20));

改為用箭頭函式就直接以箭頭來代替function

var myFunc = (a,b) =>{
    return a+b;
}
console.log(myFunc(10,20));
物件、方法與屬性
我們想要製作一個名稱為cat的物件,並且給兩個屬性名稱:Name;Age,以及一個run方法。
建立完成之後,只要用new關鍵字就能產生物件實體。例如實作一隻名為kitty的5歲貓。
var kitty = new cat("kitty", 5);
kitty物件實作完成了,我們就可以使用點(.)來呼叫物件的屬性attribute與方 法method,由於方法是函式,所以要加括號來呼叫。
console.log(kitty.Name+"是一隻"+ kitty.Age+"歲的貓");
kitty.run();

kitty.htm 完整程式碼

<script type="text/javascript">
	
	var cat = function (catName, catAge){
		this.Name = catName;
		this.Age = catAge;
		this.run = function(){
			console.log(this.Name, "跑走了!");
		};
	};

	var kitty = new cat("kitty",5);

	console.log(kitty.Name+"是一隻"+ kitty.Age+"歲的貓");
	kitty.run();
 </script>
原型鏈prototype chain 與擴充 extneds
student 繼承 person 主要使用兩個方法,一個是call()方法,一個是Object.create()方法,我們來看看這兩個方法如何使用。
call()語法如下:
otherObj.call(thisObj[, arg1,arg2,...]);

JavaScript 精選14堂課(三)

JavaScript 的內建物件,可分為四大類:
1. 日期(Date)
2. 數學(Math)
3. 字串(String)
4. 陣列(Array)
Date 日期物件
<script type="text/javascript">
	var theDate = new Date();
	var nowDT = theDate.getFullYear() + "/" +
				(theDate.getMonth() +1 )+ "/" +
				theDate.getDate() +"/" +
				theDate.getHours() +":"+
				theDate.getMinutes() + ":" +
				theDate.getSeconds();
	console.log("現在日期時間:"+nowDT);
    </script>

結果:

Tips:
setMonth()與getMonth()的數值是從0開始,0代表一月,11代表十二月,所以使用這兩個方法時都必須再加1,才是正確的月份值。

字串物件(string)
屬性
字串物件可搭配的屬性有length,作用是取字串的長度。
var name = "good job!";
len = name.length; //len的值為9

   方法

方法說明格式
toString 
將數值或物件轉換為字串
number[object].toString()
charAt()傳回指定位置index的
字元index從0開始
String.charAt(index)
charCodeAt()傳回指定位置index的Unicode編
碼,數值為0到65535之間的整
數。index從0開始
String.charCodeAt(index)
includes()搜尋字串,傳回布林值true或
flase區分大小寫
String.includes(searchString)
indexOf()搜尋字串,回傳搜尋字串第一
次相符的位置索引值,1表示
找不到。
String.indexOf(searchString)
lastIndexOf()搜尋字串,回傳搜尋字串最後
相符的位置索引值,-1表示找
不到。
String.lastIndexOf(searchString)
match()以正則表示式regexp搜尋字
串(如果輸入非regexp會自動
轉換),回傳陣列,包含
groups、index、input,找
不到會傳回null。
String.match(regexp)
matchAll()以正則表示式regexp搜尋字
串,返回所有符合的結果,
返回值是正則表示式字串疊
代器RegExpStringIterator
String.matchAll(regexp)
concat()合併字串String.concat(string1,string2)
Math 數學運算物件
Math是JavaScript內建物件,提供了數學運算常用的常數以及三角函數、對數函數和數學函數。
屬性說明
Math.Ee數學常數,自然對數函數的底數或稱為歐拉數,約為2.718
Math.LM2loge2,2的自然對數,約為0.693
Math.PI圓周率,約為3.1416

範例

let r=10;
let circleArea = r * r * Math.PI;
console.log(`半徑${r}公分的圓形面積為${circleArea}`);
陣列

宣告陣列物件

方法一:
var arrayName = new Array();
arrayName[0] = "元素一";
arrayName[1] = "元素二";

方法二:
var arrayName = new Array("元素一","元素二");

方法三:
var arrayName = ["元素一","元素二"];

陣列屬性property

array.property

取的陣列的個數
myArray.length

陣列方法method()

方法說明
sort()排列陣列元素
reverse()反轉陣列元素排列

sort()方法是將陣列排列,而reserse()方法則是將陣列反方向排列。

pop()取出陣列尾端元素
push()新增元素到陣列尾端
shit()取出陣列第一個元素
unshift()新增元素到陣列開端

JavaScript 精選14堂課(二)

程式控制結構

選擇結構
如果if及else內的程式敘述只有一行,同樣可以省略大跨號{}。例如:
if (a==1) b=1; else b=2;

也可以用三運算子?來達成,三元運算子格式如下:
條件運算式? 程式敘述1 : 程式敘述2

條件運算式成立就執行敘述1,否則就執行程式敘述2。
上述程式可以改寫為:
b = (a==1 ? 1:2);
加上括號只是為了程式易讀。
重複結構

範例:

<script>
//for
for (i=1; i<=10; i++){
    console.log(i + "平方 = "+ (i*i));
}
console.log("現在 i 值 = " +i);
</script>

範例:

let fruit = ["apple", "tomato", "Strawberry"];
for (let x in fruit) {
	console.log(fruit[x]);
}

範例:

<script>
//forEach
let fruit = ["apple", "tomato", "Strawberry"];
fruit.forEach(function(x){
     console.log(x);
});

範例:

<script>
//while 
let = 1;
while(i<=10){
    console.log(i + "平方 = " + (i*i));
}
console.log("現在i值 = "+ i);
</script>
使用while loop 有兩個重點,提醒您留意:
1.必須先指定變數的起始值。
2.條件式中的變數值的增減,必須寫在while{}內,否則變數i永遠不會改變,迴圈一直執行就會造成無窮迴圈!
<script>
// do....while
let i=1;
do {
   console.log(i + "平方 = "+ (i*i));
   i++;
}while(i<=10)

console.log("現在i值 = "+ i);
</script>
break 和continue 敘述
break跟continue敘述可以用來控制迴圈流程

break敘述的作用是強迫終止迴圈的執行,跳出最靠近的迴圈,直接執行迴圈外的第一行指令。
例如:
if (i>5) break;

continue敘述的作用是馬上回到迴圈的一開始,再繼續執行迴圈。
if(i<7) continue;
<script type="text/javascript">
	for (let a=0; a<=10; a++){
		if (a===3){
			console.log(a);
			continue;
		}
		if (a===8){
			console.log(a);
			break;
		}
		console.log("for loop a="+a);
	}
 </script>

forEach 迴圈不能使用break指令中斷循環