zoukankan      html  css  js  c++  java
  • JavaScript函数及作用域

    知识内容:

    1.JavaScript函数

    2.JavaScript全局函数及特殊函数

    3.JavaScript作用域

    4.本节练习

    参考资料:《JavaScript高级程序设计》

    一、JavaScript中的函数

    1.函数的定义

    学完python后,对函数的定义一定不再陌生了,函数对于任何一个语言来说都是核心的概念。通过函数我们可以封装任意多条语句,而且可以在任何地方任何时候调用执行。JavaScript中的函数使用function来声明定义,函数的基本语法如下:

    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!");  // 调用函数

    或者以下面的这种方式定义函数:

    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

    二、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(){...})();

    关于匿名函数详细内容:https://www.cnblogs.com/wyb666/p/9314141.html

    示例:

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

    自调函数的优点:不会产生任何全局变量

    自调函数的缺点:函数无法重复执行,适合一些一次性或初始化的任务

    (4)闭包

    关于闭包,详情看这里:https://www.cnblogs.com/wyb666/p/9314141.html

    三、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

    四、本节练习

    题目如下:

     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
  • 相关阅读:
    js实现去重字符串
    js查找水仙花数
    js实现找质因数
    jQuery插件(多级菜单)
    Pycharm安装常见问题
    Python-Excel循环写入
    1110 距离之和最小 V3
    1109 01组成的N的倍数
    1393 0和1相等串
    1043 幸运号码
  • 原文地址:https://www.cnblogs.com/wyb666/p/9326768.html
Copyright © 2011-2022 走看看