JavaScript函數及做用域

知識內容:javascript

1.JavaScript函數html

2.JavaScript全局函數及特殊函數java

3.JavaScript做用域python

4.本節練習express

 

參考資料:《JavaScript高級程序設計》數組

 

 

 

1、JavaScript中的函數瀏覽器

1.函數的定義閉包

學完python後,對函數的定義必定再也不陌生了,函數對於任何一個語言來講都是核心的概念。經過函數咱們能夠封裝任意多條語句,並且能夠在任何地方任什麼時候候調用執行。JavaScript中的函數使用function來聲明定義,函數的基本語法以下:app

1 function functionName (arg0, arg1, ..., argN){
2  statements 3 } 4 5 // 如下是一個函數示例: 6 function sayHi(name, message){ // 定義函數 7 alert("Hello " + name + ", " + message); 8 } 9 sayHi("wyb", "Good morning!"); // 調用函數

或者如下面的這種方式定義函數:ide

1 sayHi = function() {
2     console.log("Hello, world!"); 3 } 4 5 sayHi();

我的建議使用上面第二種方法定義函數

 

 

2.函數的參數與返回值

(1)函數的參數

像上面的例子中出現的參數都叫命名參數,相似python中的普通參數,在這裏不作詳細解釋

JavaScript中函數的參數在內部是用一個數組表示,函數接受的始終是這個數組,而不關心數組中包含哪些參數。實際上函數能夠經過arguments對象來訪問這個參數數組,從而獲取傳遞給函數的每個參數

arguments對象:

  • 訪問參數 - arguments[index]
  • 獲取參數個數 - length屬性
1 function sayHi(){
2     console.log("Hello " + arguments[0] + "," + arguments[1]);
3     console.log(arguments.length);   // 輸出傳入的參數個數
4 }
5 
6 sayHi("wyb", "good morning!");
7 
8 // console.log() -> 在瀏覽器中的命令行輸出

根據arguments對象實現讓函數接受任意個參數並分別實現適當的功能:

 1 function add(){
 2     if (arguments.length == 1){
 3         alert(arguments[0]); 
 4     }
 5     else if (arguments.length == 2){
 6         alert(arguments[0] + arguments[1]);
 7     }
 8 }
 9 
10 add(10);         // 10
11 add(10, 20);   //  30

另外arguments對象能夠和傳統的命名參數一塊兒結合使用:

 1 function add(num1, num2){
 2     if (arguments.length == 1){
 3         alert(num1); 
 4     }
 5     else if (arguments.length == 2){
 6         alert(num1 + arguments[1]);
 7     }
 8 }
 9 
10 add(10);         // 10
11 add(10, 20);   //  30

在上面這個程序中num1就至關於arguments[0],num2就至關於arguments[1],另外arguments的值始終和對應命名參數的值保持一致

注:沒有傳值的命名參數就被自動賦予undefined值相似變量定義時沒有初始化同樣;JavaScript中全部參數傳遞的都是值,不可能經過引用傳遞參數

 

(2)默認參數及可變參數

JavaScript中不像python那樣直接提供默認參數和可變參數,可是咱們能夠借arguments來間接實現默認參數和可變參數

arguments實現默認參數:

 1 // arguments實現默認參數:
 2 var func = function(x, y){
 3     // x默認爲1,y默認爲2
 4     var paramsNumber = arguments.length;  // 得到傳入參數的個數
 5     if (paramsNumber===0){
 6         x = 1;
 7         y = 2;
 8     }
 9     if (paramsNumber===1){
10         y = 2;
11     }
12     console.log(x+y)
13 };
14 
15 func(3, 3);
16 func(3);
17 func();

其實還有一種更簡單的方法能夠實現默認參數:

 1 // 實現默認參數:
 2 var func = function (a, b){
 3     a = a || "a的默認值";  // a未傳值時後面的值將賦給a,下面的b也是同理
 4     b = b || "b的默認值";
 5     console.log(a);
 6     console.log(b);
 7 };
 8 
 9 func(1, 2);
10 func(1);
11 func();

 

arguments實現可變參數:

 1 // arguments實現可變參數:
 2 var test = function () {
 3     // 能夠傳入任意參數
 4     var paramsNumber = arguments.length;  // 得到傳入參數的個數
 5     var sum = 0;
 6     for (var i = 0; i < paramsNumber; i += 1) {
 7         sum += arguments[i];
 8     }
 9     console.log(sum);
10 };
11 
12 test();
13 test(1, 2, 3);
14 test(1, 2, 3, 4, 5);

 

 

(3)返回值

  • JavaScript中函數能夠有也能夠沒有返回值,使用return來返回返回值
  • 函數會在return以後中止執行並當即退出,退出以後位於return以後的語句將不會執行;
  • 函數中能夠多個return
  • return也能夠不帶任何返回值
 1 // 帶返回值的函數
 2 function sum(num1, num2){
 3     return num1 + num2; 4 } 5 6 // return以後的語句不會執行 7 function sum(num1, num2){ 8 return num1 + num2; 9 alert("return以後的語句不會執行"); // 不會執行 10 } 11 12 // 包含多個return 13 function diff(num1, num2){ 14 if (num1 < num2) { 15 return num2 - num1; 16  } 17 else { 18 return num1 - num2; 19  } 20 } 21 22 // 不帶任何返回值的return 23 function sayHi(name, message){ 24 alert("Hello " + name + ", " + message); 25 return; 26 } 27 sayHi("wyb", "Good morning!"); 

 

 

3.函數中的局部變量與全局變量

(1)局部變量

在JavaScript函數內部聲明的變量(使用 var)是局部變量,因此只能在函數內部訪問它(該變量的做用域是函數內部)。只要函數運行完畢,本地變量就會被刪除。

 

(2)全局變量:

在函數外聲明的變量是全局變量,網頁上的全部腳本和函數都能訪問它。另外在函數內聲明的變量若是省略var就是定義了全局變量

 

(3)變量生存週期:

JavaScript變量的生命期從它們被聲明的時間開始:

  • 局部變量會在函數運行之後被刪除
  • 全局變量會在頁面關閉後被刪除

 

 

4.函數注意事項

每一個函數都是Function類型的實例,並且都與其餘引用類型同樣具備屬性和方法。因爲函數是對象,所以函數名實際上也是一個指向函數對象的指針,不會與某個函數綁定

除了和其餘語言同樣的函數定義方法(函數聲明),JavaScript中的函數還能夠這樣定義(函數表達式):

1 var sum = function(num1, num2){
2     return num1 + num2
3 }

總結:在JavaScript中函數是對象,函數名是指針

(1)沒有重載(深刻理解)

傳統的函數重載:

 1 var addSomeNumber = function (sum){
 2     return num + 100;
 3 }
 4 
 5 var addSomeNumber = function (sum){
 6     return num + 200;
 7 }
 8 
 9 var res = addSomeNumber(100) 
10 console.log(res)  // 300 

深刻理解:在JavaScript中函數名實質是一個指針,也就是一個變量,後一個函數名實際上覆蓋了前一個函數名,就相似變量賦值兩次後最後值是最後一次賦值的值同樣

 

(2)函數聲明與函數表達式

JavaScript解釋器對函數聲明和函數表達式並不是一視同仁,解釋器會先讀取函數聲明,並使其在執行代碼前可用(能夠訪問);至於函數表達式,則必須等到解析器執行到它所在的代碼行,纔會真正被解釋執行

 

(3)做爲值的函數

JavaScript中的函數名自己就是變量,故函數能夠做爲值來使用,能夠像傳遞參數同樣把一個函數傳遞給另外一個函數,也能夠將一個函數做爲另外一個函數的結果返回

 

(4)函數內部屬性

函數內部中有兩個特殊的屬性:arguments和this。

  • arguments中保存函數的全部參數
  • this是引用的是函數據以執行的環境對象,在網頁的全局做用域中this代指的就是window

 

(5)函數的屬性和方法

函數的屬性:

  • length:表示函數但願接受的命名參數的個數
  • prototype:保存全部實例方法的真正所在,不過各個實例方法經過各自對象的實例訪問

 

函數的方法:

apply()和call():都是在特定的做用域中調用函數實際上等於設置函數體內this對象的值

apply:接受兩個參數,一個是在其中運行函數的做用域,另外一個是參數數組(能夠是普通數組也能夠是arguments對象)

 1 function sum(num1, num2){
 2     return num1 + num2
 3 }
 4 
 5 function callSum1(num1, num2){
 6     return sum.apply(this, arguments)  
 7 }
 8 
 9 function callSum2(num1, num2){
10     return sum.apply(this, [num1, num2])  
11 }
12 
13 console.log(callSum1(1, 2))  // 3
14 console.log(callSum2(1, 2))  // 3

 

call:做用和apply方法同樣,不一樣的是第二個參數必須一個個列出來

1 function sum(num1, num2){
2     return num1 + num2
3 }
4 
5 function callSum1(num1, num2){
6     return sum.call(this, num1, num2)  
7 }
8 
9 console.log(callSum1(1, 2))  // 3

apply和call方法真正的做用是擴充函數賴以運行的做用域

 

bind():建立一個函數的實例,其this值會被綁定到傳給bind方法的值

 1 window.color = "red"
 2 var o = { 
 3     color: "blue"
 4 }
 5 
 6 function sayColor(){
 7     console.log(this.color)
 8 }
 9 
10 var objectSayColor = sayColor.bind(o)
11 objectSayColor()   // blue

 

 

5.JavaScript3種基本函數

(1)普通函數

上面全部的函數均是普通函數
1 function func(arg){
2     return true; 3 }

 

(2)函數表達式 - 沒有固定名字的函數

1 var func = function(arg){
2      return "tony"; 3 }

 

(3)自執行函數(匿名函數) - 不須要名字的函數

程序從上到下解釋執行,建立函數而且自動執行

1 (function(arg){
2  console.log(arg); 3 })('123')

關於匿名函數詳細介紹:http://www.cnblogs.com/wyb666/p/9314141.html

 

 

 

2、JavaScript全局函數及特殊函數

1.JavaScript全局函數介紹

全局函數與內置對象的屬性或方法不是一個概念。全局函數它不屬於任何一個內置對象,能夠在JavaScript程序中直接調用

 

 

2.JavaScript全局函數詳細內容

(1)數據轉換相關:

parseInt(String,radix):返回轉換成整數的值。

parseFloat(string):返回轉換成浮點型的值。

isFinite(value):檢測某個是是不是無窮值。

isNaN(value):檢測某個值是不是NaN。

encodeURI(uri):將字符串編碼爲URI

decodeURI(uri):解碼某個編碼的URI。

encodeURIComponent(uri):將字符串編碼爲URI組件

decodeURIComponent():解碼一個編碼的URI組件

escape():對字符串進行編碼

unescape():解碼由escape()編碼的字符串

Number(object):把對象的值轉換爲數字

String():把對象的值轉換爲字符串

 

(2)其餘:

eval():將JavaScript字符串看成腳原本執行

 

詳細說明以下圖:

 

 

3.JavaScript中的特殊形式的函數 

(1)JavaScript中的函數也是數據類型

在JavaScript中,函數也是一種數據類型,是function類型,不過它有兩個特徵:裏面包含的是代碼和能夠執行

 

(2)回調函數

回調函數:能夠將匿名函數做爲參數傳遞給其餘函數,接受方函數就能夠經過傳遞進來的函數完成某些功能

 1 // 回調函數示例:
 2 var calc = function (x, y) {
 3     return x() + y()
 4 };
 5 
 6 var test1 = function () {
 7     return 1
 8 };
 9 
10 var test2 = function () {
11     return 2
12 };
13 
14 console.log(calc(test1, test2));  // 3
15 console.log(calc(function () { return 3 }, function () { return 3 } ));  // 6

 

回調函數的優點:

  • 在不作命名的時候傳遞函數,這樣能夠節省全局變量
  • 將一個函數調用委託給另外一個函數,節省一些代碼的編寫
  • 有助於提高性能

 

關於節省代碼看如下示例:

 1 // 回調函數節省代碼的示例:
 2 var test = function (a, b, c) {
 3     var arr = [];
 4     for (var i = 0; i < 3; i++) {
 5         arr[i] = arguments[i] * 2;
 6     }
 7     return arr
 8 };
 9 var jia = function (s) {
10     return s + 1;
11 };
12 
13 var arr1 = [];
14 arr1 = test(10, 20, 30);
15 console.log(arr1);  // [20, 40, 60]
16 for (var i = 0; i < 3; i++) {
17     arr1[i] = jia(arr1[i]);
18 }
19 console.log(arr1);  // [21, 41, 61]
20 
21 // 上述代碼用回調函數實現:
22 var addOne = function (n) {
23     return n+1;
24 };
25 var test = function (a, b, c, callback) {
26     var arr = [];
27     for (var i = 0; i < 3; i++) {
28         arr[i] = callback(arguments[i] * 2);
29     }
30     return arr;
31 };
32 console.log(test(10, 20, 30, addOne));  // [21, 41, 61]
33 console.log(test(10, 20, 30, function (n){return n+1;}));  // [21, 41, 61]

 

另外用過函數自帶的方法call()和apply()也能夠實現回調函數,只不過這兩個函數參數有特定的要求:

call方法傳入的參數爲函數名和函數參數(一個個的列出來)

apply方法傳入的參數爲函數名和參數數組

上述兩個方法實例以下:

1 // call和apply方法:
2 var test = function (a, b) {
3     return a*b;
4 };
5 console.log(test.call(test, 3, 5));  // 15
6 var params = [3, 5];
7 console.log(test.apply(test, params));  // 15

注:上述傳入的函數名能夠用this代替,this代指當前對象即test函數

 

(3)自調函數(自執行函數)

自調函數:能夠經過匿名函數來執行某些一次性的任務,匿名函數的基本形式爲(function(){...})();

關於匿名函數詳細內容:http://www.javashuo.com/article/p-gafukbzg-ba.html

示例:

1 // 自調用函數:
2 (function () {
3     alert("this a test!")
4 })();
5 (function (a, b) {
6     alert(a+b);
7 })(3, 2);

 

自調函數的優勢:不會產生任何全局變量

自調函數的缺點:函數沒法重複執行,適合一些一次性或初始化的任務

 

(4)閉包

關於閉包,詳情看這裏:http://www.javashuo.com/article/p-gafukbzg-ba.html

 

 

 

3、JavaScript做用域

1.JavaScript執行環境

執行環境:定義變量及函數有權訪問的數據,決定它們各自的行爲。每一個執行環境都有一個與之關聯的變量對象,環境中定義的全部變量和函數都保存在這個對象中

某個執行環境中的全部代碼執行完畢後,該環境被銷燬,保存在其中的全部變量和函數定義也隨之銷燬(全局執行環境直到應用程序退出-例如關閉網頁或瀏覽器時纔會被銷燬)

函數與執行環境:每一個函數都有本身的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中,而在函數執行以後,棧將其環境彈出,把控制權返回給以前的執行環境

 

 

2.做用域

什麼是做用域:一段程序代碼中所用到的名字並不老是有效/可用的,而限定這個名字的可用性的代碼範圍就是這個名字的做用域

  • C/C++/C#/Java等語言以代碼塊爲做用域 -> 代碼塊以{}區分
  • python/JavaScript以函數爲做用域

關於JavaScript的做用域:JavaScript中每一個函數都有本身的做用域,當出現函數嵌套時,就出現了做用域鏈。當內層函數使用變量時,會根據做用域鏈從內到外一層層的循環,若是不存在,則異常

 1 public void Func(){
 2     if(1==1) 3  { 4 string name = "java"; 5 console.writeline(name); // 正常運行 6  } 7 console.writeline(name); // 報錯 8 } 9 10 Func()
1 def func():
2     if 1==1: 3 name = "python" 4 print(name) // 正常運行 5 print(name) // 正常運行 6 7 func() 8 print(name) // 報錯
function func(){
    if(1==1){ var name = "javascript"; console.log(name); // 正常運行  } console.log(name); // 正常運行 } func(); console.log(name); // 報錯

 

 

3.做用域鏈

當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈

做用域鏈的做用:保證對執行環境有權訪問的全部變量和函數的有序訪問

關於做用域和做用域鏈:

  • 函數的做用域在函數未被調用以前就已經建立
  • 函數的做用域存在做用域鏈,做用域鏈也是在函數被調用以前建立的
 1 // 函數的做用域在函數未被調用以前肯定
 2 name = "wyb"
 3 function func(){
 4     var name = "xxx"; 5 function inner(){ 6 var name = "ooo"; 7 console.log(name); // 輸出: ooo 8  } 9 10  inner() 11 } 12 13 func(); 14 15 16 name = "wyb" 17 function func(){ 18 var name = "xxx"; 19 function inner(){ 20 // var name = "ooo"; 21 console.log(name); // 輸出: xxx 22  } 23 24  inner() 25 } 26 27 func() 28 29 30 name = "wyb" 31 function func(){ 32 // var name = "xxx"; 33 function inner(){ 34 // var name = "ooo"; 35 console.log(name); // 輸出: wyb 36  } 37 38  inner() 39 } 40 41 func() 42 43 44 // 函數的做用域存在做用域鏈 做用域鏈也是在函數被調用以前建立的 45 name = "wyb" 46 function func(){ 47 var name = "xxx"; 48 function inner(){ 49 var name = "ooo"; 50 console.log(name); // 輸出: ooo 51  } 52 53 return inner; 54 } 55 56 var ret = func() 57 ret() 58 59 60 name = "wyb" 61 function func(){ 62 var name = "xxx"; 63 function inner(){ 64 // var name = "ooo"; 65 console.log(name); // 輸出: xxx 66  } 67 68 return inner; 69 } 70 71 var ret = func() 72 ret() 73 74 75 name = "wyb" 76 function func(){ 77 // var name = "xxx"; 78 function inner(){ 79 // var name = "ooo"; 80 console.log(name); // 輸出: wyb 81  } 82 83 return inner; 84 } 85 86 var ret = func() 87 ret()

注意如下問題:

 1         name = "wyb"
 2     function func(){
 3         var name = "xxx"; 4 function inner(){ 5 // var name = "ooo"; 6 console.log(name); // 輸出: tony 7  } 8 var name = "tony"; 9 10 return inner; 11  } 12 13 var ret = func() 14 ret()

輸出tony的緣由是:

 

 

4.函數內局部變量會提早聲明

 1 // 函數內部局部變量會提早聲明
 2 // 當解釋程序時,在函數提早生成做用域鏈的同時找到內部全部的局部變量
 3 // 而後提早聲明變量  var xxoo;  // 此時輸出xxoo的值爲undefined
 4 
 5 function func(){
 6  console.log(xxoo); 7 } 8 9 func() // 程序直接報錯 10 11 12 function func(){ 13  console.log(xxoo); 14 var xxoo = "666"; 15 } 16 17 func() // undefined

 

 

 

4、本節練習

題目以下:

 1 練習要求:
 2 每一個題使用函數完成,必須寫相應的單元測試代碼
 3 
 4 第一題
 5 參數是一個只包含數字的 array,求 array 的乘積
 6 
 7 第二題
 8 返回一個數的絕對值
 9 
10 第三題
11 參數是一個只包含數字的 array,求 array 中全部數字的平均數
12 
13 第四題
14 參數是一個只包含數字的 array,求 array 中最小的數字
15 
16 第五題
17 參數是一個數字 n, 返回如下序列的結果: 1 - 2 + 3 - 4 + 5 ... n
18 
19 第六題
20 參數是一個數字 n, 返回如下序列的結果: 1 + 2 - 3 + 4 - ... n
21 
22 第七題
23 實現 fac 函數: 接受一個參數 n, 返回 n 的階乘, 1 * 2 * 3 * ... * n
24 
25 第八題
26 注意 下面幾題中的參數 op 是 operator(操做符) 的縮寫! 
27 實現 apply 函數,參數以下: 
28 op 是 string 類型, 值是 '+' '-' '*' '/' 其中之一; a b 分別是 2 個數字; 根據 op 對 a b 運算並返回結果(加減乘除)
29 
30 第九題
31 實現 applyList 函數: op 是 '+' '-' '*' '/' 其中之一; oprands 是一個只包含數字的 array; 根據 op 對 oprands 中的元素進行運算並返回結果;
32 例如, 下面的調用返回 -4 var n = applyList('-', [3, 4, 2, 1]) log(n)
33 
34 第十題
35 實現 applyCompare 函數: 參數以下: expression 是一個 array(數組), 包含了 3 個元素:
36 第一個元素是 op, 值是 '>' '<' '==' 其中之一; 剩下兩個元素分別是 2 個數字; 根據 op 對數字運算並返回結果(結果是 true 或者 false)

 

實現代碼:

  1     // 自定義log
  2     var log = function () {
  3         console.log.apply(this, arguments);
  4     };
  5 
  6 
  7     // 套路, 照抄便可
  8     // 單元測試用的函數:
  9     var ensure = function(condition, message) {
 10         // 若是condition爲false 在控制檯輸出message
 11         if (!condition) {
 12             log(message)
 13         }
 14     };
 15 
 16 
 17     // 做業 1
 18     // 參數是一個只包含數字的 array
 19     // 求 array 的乘積
 20     // 函數定義是
 21     var product = function(array) {
 22         // 先設置一個變量用來存 乘積
 23         var s = 1;
 24         // 遍歷數組
 25         for(var i = 0; i < array.length; i++) {
 26             // 用變量 n 保存元素值
 27             var n = array[i];
 28             // 累乘到變量 s
 29             s = s * n
 30             // 縮寫是以下形式
 31             // s *= n
 32         }
 33         // 循環結束, 如今 s 裏面存的是數組中全部元素的乘了
 34         return s
 35     };
 36 
 37     // 如下就是單元測試代碼 後面的以test開頭的函數同理也是單元測試代碼
 38     // var testProduct = function() {
 39     //     ensure(product([1, 2, 3]) === 6, 'test product 1');
 40     //     ensure(product([1, 2, 0]) === 0, 'test product 2');
 41     // };
 42     // testProduct();
 43 
 44 
 45     // 做業 2
 46     // 返回一個數的絕對值
 47     // 函數定義是
 48     var abs = function(n) {
 49         if (n < 0) {
 50             return -n
 51         } else {
 52             return n
 53         }
 54     };
 55 
 56     // var testAbs = function() {
 57     //     ensure(abs(0) === 0, 'abs 0 錯誤');
 58     //     ensure(abs(-6) === 6, 'abs -6 錯誤');
 59     //     ensure(abs(5) === 5, 'abs 5 錯誤');
 60     // };
 61     // testAbs();
 62 
 63 
 64     // 做業 3
 65     // 參數是一個只包含數字的 array
 66     // 求 array 中全部數字的平均數
 67     // 函數定義是
 68     var sum = function (array) {
 69         // 求數組的和
 70         var n = array.length;
 71         var s = 0;
 72         for(var i=0; i<n; i++){
 73             s += array[i];
 74         }
 75 
 76         return s;
 77     };
 78 
 79     var average = function(array) {
 80         // 先求和
 81         var s = sum(array);
 82         // 再求平均數
 83         var avg = s/array.length;
 84 
 85         return avg;
 86     };
 87 
 88     // var testAverage = function () {
 89     //     ensure(average([1, 2, 3]) === 2, "average 2 錯誤");
 90     //     ensure(average([0]) === 0, "average 0 錯誤");
 91     //     ensure(average([1, 1, 0, 0]) === 0.5, "average 0.5 錯誤");
 92     // };
 93     // testAverage();
 94 
 95 
 96     // 做業 4
 97     // 參數是一個只包含數字的 array
 98     // 求 array 中最小的數字
 99     // 函數定義是
100     var min = function(array) {
101         var minNum = array[0];
102         for(var i=0; i<array.length; i++){
103             if(array[i] < minNum){
104                 minNum = array[i];
105             }
106         }
107 
108         return minNum
109     };
110 
111     // var testMin = function () {
112     //     ensure(min([1, 2, 3, 4, 5]) === 1, "min 1 錯誤");
113     //     ensure(min([0, 0, 5]) === 0, "min 0 錯誤");
114     //     ensure(min([3, 3, 3, 4, 5]) === 3, "min 3 錯誤");
115     //     ensure(min([111, 112, 113, 114, 99]) === 99, "min 99 錯誤");
116     // };
117     // testMin();
118 
119 
120     // 做業 5
121     /*
122     參數是一個數字 n
123     返回如下序列的結果
124     1 - 2 + 3 - 4 + 5 ... n
125     */
126     var sum1 = function(n) {
127         var sum = 0;
128         for(var i=1; i<=n; i++){
129             if(i%2 === 0){
130                 sum -= i;
131             }else{
132                 sum += i;
133             }
134         }
135 
136         return sum;
137     };
138 
139     // var testSum1 = function () {
140     //     ensure(sum1(5) === 3, "sum1 5 錯誤");
141     //     ensure(sum1(1) === 1, "sum1 1 錯誤");
142     //     ensure(sum1(2) === -1, "sum1 2 錯誤");
143     //     ensure(sum1(3) === 2, "sum1 3 錯誤");
144     // };
145     // testSum1();
146 
147 
148     // 做業 6
149     /*
150     參數是一個數字 n
151     返回如下序列的結果
152     1 + 2 - 3 + 4 - ... n
153     */
154     var sum2 = function(n) {
155         var sum = 0;
156         for(var i=1; i<=n; i++){
157             if(i%2 === 0){
158                 sum += i;
159             }else{
160                 sum -= i;
161             }
162         }
163 
164         return sum+2;
165     };
166 
167     // var testSum2 = function () {
168     //     ensure(sum2(1) === 1, "sum2 1 錯誤");
169     //     ensure(sum2(2) === 3, "sum2 2 錯誤");
170     //     ensure(sum2(3) === 0, "sum2 3 錯誤");
171     //     ensure(sum2(4) === 4, "sum2 4 錯誤");
172     //     ensure(sum2(5) === -1, "sum2 5 錯誤");
173     // };
174     // testSum2();
175 
176 
177     // 做業 7
178     /*
179     實現 fac 函數
180     接受一個參數 n
181     返回 n 的階乘, 1 * 2 * 3 * ... * n
182     */
183     var fac = function(n) {
184         var s = 1;
185         for(var i=1; i<=n; i++){
186             s *= i;
187         }
188 
189         return s;
190     };
191 
192     // var testFac = function () {
193     //     ensure(fac(1) === 1, "fac 1 錯誤");
194     //     ensure(fac(2) === 2, "fac 2 錯誤");
195     //     ensure(fac(3) === 6, "fac 3 錯誤");
196     //     ensure(fac(4) === 24, "fac 4 錯誤");
197     //     ensure(fac(5) === 120, "fac 5 錯誤");
198     // };
199     // testFac();
200 
201 
202     /*
203     注意 下面幾題中的參數 op 是 operator(操做符) 的縮寫
204 
205     做業 8
206     實現 apply 函數
207     參數以下
208     op 是 string 類型, 值是 '+' '-' '*' '/' 其中之一
209     a b 分別是 2 個數字
210     根據 op 對 a b 運算並返回結果(加減乘除)
211     */
212     var apply = function(op, a, b) {
213         if(op === '+') {
214             return a + b
215         }
216         if(op === '-') {
217             return a - b
218         }
219         if(op === '*') {
220             return a * b
221         }
222         if(op === '/') {
223             return a / b
224         }
225     };
226 
227     // var testApply = function () {
228     //     ensure(apply("+", 1, 2) === 3, "apply(1+2) 錯誤");
229     //     ensure(apply("-", 1, 2) === -1, "apply(1-2) 錯誤");
230     //     ensure(apply("*", 1, 2) === 2, "apply(1*2) 錯誤");
231     //     ensure(apply("/", 1, 2) === 0.5, "apply(1/2) 錯誤");
232     // };
233     // testApply();
234 
235 
236     /*
237     做業 9
238     實現 applyList 函數
239     op 是 '+' '-' '*' '/' 其中之一
240     oprands 是一個只包含數字的 array
241     根據 op 對 oprands 中的元素進行運算並返回結果
242     例如, 下面的調用返回 -4
243     var n = applyList('-', [3, 4, 2, 1])
244     log(n)
245     // 結果是 -4, 用第一個數字減去全部的數字
246     */
247     var applyList = function(op, oprands) {
248         var n = oprands.length;
249         var res = oprands[0];
250         if(op === '+') {
251             for(var i=1; i<n; i++){
252                 res += oprands[i];
253             }
254         }
255         if(op === '-') {
256             for(var i=1; i<n; i++){
257                 res -= oprands[i];
258             }
259         }
260         if(op === '*') {
261             for(var i=1; i<n; i++){
262                 res *= oprands[i];
263             }
264         }
265         if(op === '/') {
266             for(var i=1; i<n; i++){
267                 res /= oprands[i];
268             }
269         }
270 
271         return res;
272     };
273 
274     // var testApplyList = function () {
275     //     ensure(applyList("+", [1, 2, 3, 4]) === 10, "applyList + 出錯");
276     //     ensure(applyList("+", [1]) === 1, "applyList + 出錯");
277     //     ensure(applyList("-", [4, 2, 3, 4]) === -5, "applyList - 出錯");
278     //     ensure(applyList("-", [1]) === 1, "applyList - 出錯");
279     //     ensure(applyList("*", [1, 2, 3, 4]) === 24, "applyList * 出錯");
280     //     ensure(applyList("*", [1]) === 1, "applyList * 出錯");
281     //     ensure(applyList("/", [3]) === 3, "applyList / 3 出錯");
282     //     ensure(applyList("/", [4, 2, 1]) === 2, "applyList / 2 出錯");
283     // };
284     // testApplyList();
285 
286 
287     /*
288     做業 10
289     實現 applyCompare 函數
290     參數以下
291     expression 是一個 array(數組), 包含了 3 個元素
292     第一個元素是 op, 值是 '>' '<' '==' 其中之一
293     剩下兩個元素分別是 2 個數字
294     根據 op 對數字運算並返回結果(結果是 true 或者 false)
295     */
296     var applyCompare = function(expression) {
297         var op = expression[0];
298         var a = expression[1];
299         var b = expression[2];
300         if (op == '<') {
301             return a < b
302         }
303         if (op == '>') {
304             return a > b
305         }
306         if (op == '==') {
307             return a == b
308         }
309     };
310 
311     // var testApplyCompare = function () {
312     //     ensure(applyCompare(["<", 1, 2]) === true, "applyCompare 1<2 錯誤");
313     //     ensure(applyCompare(["<", 2, 1]) === false, "applyCompare 2<1 錯誤");
314     //     ensure(applyCompare([">", 2, 1]) === true, "applyCompare 2>1 錯誤");
315     //     ensure(applyCompare([">", 1, 2]) === false, "applyCompare 1>2 錯誤");
316     //     ensure(applyCompare(["==", 1, 1]) === true, "applyCompare 1==1  錯誤");
317     //     ensure(applyCompare(["==", 1, 2]) === false, "applyCompare 1==2 錯誤");
318     // };
319     // testApplyCompare();
View Code
相關文章
相關標籤/搜索