JavaScript函数及作用域

时间:2021-01-17 04:28:40

知识内容:

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实现默认参数:

 // arguments实现默认参数:
var func = function(x, y){
// x默认为1,y默认为2
var paramsNumber = arguments.length; // 获得传入参数的个数
if (paramsNumber===0){
x = 1;
y = 2;
}
if (paramsNumber===1){
y = 2;
}
console.log(x+y)
}; func(3, 3);
func(3);
func();

其实还有一种更简单的方法可以实现默认参数:

 // 实现默认参数:
var func = function (a, b){
a = a || "a的默认值"; // a未传值时后面的值将赋给a,下面的b也是同理
b = b || "b的默认值";
console.log(a);
console.log(b);
}; func(1, 2);
func(1);
func();

arguments实现可变参数:

 // arguments实现可变参数:
var test = function () {
// 可以传入任意参数
var paramsNumber = arguments.length; // 获得传入参数的个数
var sum = 0;
for (var i = 0; i < paramsNumber; i += 1) {
sum += arguments[i];
}
console.log(sum);
}; test();
test(1, 2, 3);
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字符串当作脚本来执行

详细说明如下图:

JavaScript函数及作用域

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

(1)JavaScript中的函数也是数据类型

在JavaScript中,函数也是一种数据类型,是function类型,不过它有两个特征:里面包含的是代码和可以执行

(2)回调函数

回调函数:可以将匿名函数作为参数传递给其他函数,接受方函数就可以通过传递进来的函数完成某些功能

 // 回调函数示例:
var calc = function (x, y) {
return x() + y()
}; var test1 = function () {
return 1
}; var test2 = function () {
return 2
}; console.log(calc(test1, test2)); //
console.log(calc(function () { return 3 }, function () { return 3 } )); //

回调函数的优势:

  • 在不做命名的时候传递函数,这样可以节省全局变量
  • 将一个函数调用委托给另一个函数,节省一些代码的编写
  • 有助于提升性能

关于节省代码看以下示例:

 // 回调函数节省代码的示例:
var test = function (a, b, c) {
var arr = [];
for (var i = 0; i < 3; i++) {
arr[i] = arguments[i] * 2;
}
return arr
};
var jia = function (s) {
return s + 1;
}; var arr1 = [];
arr1 = test(10, 20, 30);
console.log(arr1); // [20, 40, 60]
for (var i = 0; i < 3; i++) {
arr1[i] = jia(arr1[i]);
}
console.log(arr1); // [21, 41, 61] // 上述代码用回调函数实现:
var addOne = function (n) {
return n+1;
};
var test = function (a, b, c, callback) {
var arr = [];
for (var i = 0; i < 3; i++) {
arr[i] = callback(arguments[i] * 2);
}
return arr;
};
console.log(test(10, 20, 30, addOne)); // [21, 41, 61]
console.log(test(10, 20, 30, function (n){return n+1;})); // [21, 41, 61]

另外用过函数自带的方法call()和apply()也可以实现回调函数,只不过这两个函数参数有特定的要求:

call方法传入的参数为函数名和函数参数(一个个的列出来)

apply方法传入的参数为函数名和参数数组

上述两个方法实例如下:

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

注:上述传入的函数名可以用this代替,this代指当前对象即test函数

(3)自调函数(自执行函数)

自调函数:可以通过匿名函数来执行某些一次性的任务,匿名函数的基本形式为(function(){...})();

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

示例:

 // 自调用函数:
(function () {
alert("this a test!")
})();
(function (a, b) {
alert(a+b);
})(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的原因是:

JavaScript函数及作用域

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

四、本节练习

题目如下:

 练习要求:
每个题使用函数完成,必须写相应的单元测试代码 第一题
参数是一个只包含数字的 array,求 array 的乘积 第二题
返回一个数的绝对值 第三题
参数是一个只包含数字的 array,求 array 中所有数字的平均数 第四题
参数是一个只包含数字的 array,求 array 中最小的数字 第五题
参数是一个数字 n, 返回以下序列的结果: 1 - 2 + 3 - 4 + 5 ... n 第六题
参数是一个数字 n, 返回以下序列的结果: 1 + 2 - 3 + 4 - ... n 第七题
实现 fac 函数: 接受一个参数 n, 返回 n 的阶乘, 1 * 2 * 3 * ... * n 第八题
注意 下面几题中的参数 op 是 operator(操作符) 的缩写!
实现 apply 函数,参数如下:
op 是 string 类型, 值是 '+' '-' '*' '/' 其中之一; a b 分别是 2 个数字; 根据 op 对 a b 运算并返回结果(加减乘除) 第九题
实现 applyList 函数: op 是 '+' '-' '*' '/' 其中之一; oprands 是一个只包含数字的 array; 根据 op 对 oprands 中的元素进行运算并返回结果;
例如, 下面的调用返回 -4 var n = applyList('-', [3, 4, 2, 1]) log(n) 第十题
实现 applyCompare 函数: 参数如下: expression 是一个 array(数组), 包含了 3 个元素:
第一个元素是 op, 值是 '>' '<' '==' 其中之一; 剩下两个元素分别是 2 个数字; 根据 op 对数字运算并返回结果(结果是 true 或者 false)

实现代码:

     // 自定义log
var log = function () {
console.log.apply(this, arguments);
}; // 套路, 照抄即可
// 单元测试用的函数:
var ensure = function(condition, message) {
// 如果condition为false 在控制台输出message
if (!condition) {
log(message)
}
}; // 作业 1
// 参数是一个只包含数字的 array
// 求 array 的乘积
// 函数定义是
var product = function(array) {
// 先设置一个变量用来存 乘积
var s = 1;
// 遍历数组
for(var i = 0; i < array.length; i++) {
// 用变量 n 保存元素值
var n = array[i];
// 累乘到变量 s
s = s * n
// 缩写是如下形式
// s *= n
}
// 循环结束, 现在 s 里面存的是数组中所有元素的乘了
return s
}; // 以下就是单元测试代码 后面的以test开头的函数同理也是单元测试代码
// var testProduct = function() {
// ensure(product([1, 2, 3]) === 6, 'test product 1');
// ensure(product([1, 2, 0]) === 0, 'test product 2');
// };
// testProduct(); // 作业 2
// 返回一个数的绝对值
// 函数定义是
var abs = function(n) {
if (n < 0) {
return -n
} else {
return n
}
}; // var testAbs = function() {
// ensure(abs(0) === 0, 'abs 0 错误');
// ensure(abs(-6) === 6, 'abs -6 错误');
// ensure(abs(5) === 5, 'abs 5 错误');
// };
// testAbs(); // 作业 3
// 参数是一个只包含数字的 array
// 求 array 中所有数字的平均数
// 函数定义是
var sum = function (array) {
// 求数组的和
var n = array.length;
var s = 0;
for(var i=0; i<n; i++){
s += array[i];
} return s;
}; var average = function(array) {
// 先求和
var s = sum(array);
// 再求平均数
var avg = s/array.length; return avg;
}; // var testAverage = function () {
// ensure(average([1, 2, 3]) === 2, "average 2 错误");
// ensure(average([0]) === 0, "average 0 错误");
// ensure(average([1, 1, 0, 0]) === 0.5, "average 0.5 错误");
// };
// testAverage(); // 作业 4
// 参数是一个只包含数字的 array
// 求 array 中最小的数字
// 函数定义是
var min = function(array) {
var minNum = array[0];
for(var i=0; i<array.length; i++){
if(array[i] < minNum){
minNum = array[i];
}
} return minNum
}; // var testMin = function () {
// ensure(min([1, 2, 3, 4, 5]) === 1, "min 1 错误");
// ensure(min([0, 0, 5]) === 0, "min 0 错误");
// ensure(min([3, 3, 3, 4, 5]) === 3, "min 3 错误");
// ensure(min([111, 112, 113, 114, 99]) === 99, "min 99 错误");
// };
// testMin(); // 作业 5
/*
参数是一个数字 n
返回以下序列的结果
1 - 2 + 3 - 4 + 5 ... n
*/
var sum1 = function(n) {
var sum = 0;
for(var i=1; i<=n; i++){
if(i%2 === 0){
sum -= i;
}else{
sum += i;
}
} return sum;
}; // var testSum1 = function () {
// ensure(sum1(5) === 3, "sum1 5 错误");
// ensure(sum1(1) === 1, "sum1 1 错误");
// ensure(sum1(2) === -1, "sum1 2 错误");
// ensure(sum1(3) === 2, "sum1 3 错误");
// };
// testSum1(); // 作业 6
/*
参数是一个数字 n
返回以下序列的结果
1 + 2 - 3 + 4 - ... n
*/
var sum2 = function(n) {
var sum = 0;
for(var i=1; i<=n; i++){
if(i%2 === 0){
sum += i;
}else{
sum -= i;
}
} return sum+2;
}; // var testSum2 = function () {
// ensure(sum2(1) === 1, "sum2 1 错误");
// ensure(sum2(2) === 3, "sum2 2 错误");
// ensure(sum2(3) === 0, "sum2 3 错误");
// ensure(sum2(4) === 4, "sum2 4 错误");
// ensure(sum2(5) === -1, "sum2 5 错误");
// };
// testSum2(); // 作业 7
/*
实现 fac 函数
接受一个参数 n
返回 n 的阶乘, 1 * 2 * 3 * ... * n
*/
var fac = function(n) {
var s = 1;
for(var i=1; i<=n; i++){
s *= i;
} return s;
}; // var testFac = function () {
// ensure(fac(1) === 1, "fac 1 错误");
// ensure(fac(2) === 2, "fac 2 错误");
// ensure(fac(3) === 6, "fac 3 错误");
// ensure(fac(4) === 24, "fac 4 错误");
// ensure(fac(5) === 120, "fac 5 错误");
// };
// testFac(); /*
注意 下面几题中的参数 op 是 operator(操作符) 的缩写 作业 8
实现 apply 函数
参数如下
op 是 string 类型, 值是 '+' '-' '*' '/' 其中之一
a b 分别是 2 个数字
根据 op 对 a b 运算并返回结果(加减乘除)
*/
var apply = function(op, a, b) {
if(op === '+') {
return a + b
}
if(op === '-') {
return a - b
}
if(op === '*') {
return a * b
}
if(op === '/') {
return a / b
}
}; // var testApply = function () {
// ensure(apply("+", 1, 2) === 3, "apply(1+2) 错误");
// ensure(apply("-", 1, 2) === -1, "apply(1-2) 错误");
// ensure(apply("*", 1, 2) === 2, "apply(1*2) 错误");
// ensure(apply("/", 1, 2) === 0.5, "apply(1/2) 错误");
// };
// testApply(); /*
作业 9
实现 applyList 函数
op 是 '+' '-' '*' '/' 其中之一
oprands 是一个只包含数字的 array
根据 op 对 oprands 中的元素进行运算并返回结果
例如, 下面的调用返回 -4
var n = applyList('-', [3, 4, 2, 1])
log(n)
// 结果是 -4, 用第一个数字减去所有的数字
*/
var applyList = function(op, oprands) {
var n = oprands.length;
var res = oprands[0];
if(op === '+') {
for(var i=1; i<n; i++){
res += oprands[i];
}
}
if(op === '-') {
for(var i=1; i<n; i++){
res -= oprands[i];
}
}
if(op === '*') {
for(var i=1; i<n; i++){
res *= oprands[i];
}
}
if(op === '/') {
for(var i=1; i<n; i++){
res /= oprands[i];
}
} return res;
}; // var testApplyList = function () {
// ensure(applyList("+", [1, 2, 3, 4]) === 10, "applyList + 出错");
// ensure(applyList("+", [1]) === 1, "applyList + 出错");
// ensure(applyList("-", [4, 2, 3, 4]) === -5, "applyList - 出错");
// ensure(applyList("-", [1]) === 1, "applyList - 出错");
// ensure(applyList("*", [1, 2, 3, 4]) === 24, "applyList * 出错");
// ensure(applyList("*", [1]) === 1, "applyList * 出错");
// ensure(applyList("/", [3]) === 3, "applyList / 3 出错");
// ensure(applyList("/", [4, 2, 1]) === 2, "applyList / 2 出错");
// };
// testApplyList(); /*
作业 10
实现 applyCompare 函数
参数如下
expression 是一个 array(数组), 包含了 3 个元素
第一个元素是 op, 值是 '>' '<' '==' 其中之一
剩下两个元素分别是 2 个数字
根据 op 对数字运算并返回结果(结果是 true 或者 false)
*/
var applyCompare = function(expression) {
var op = expression[0];
var a = expression[1];
var b = expression[2];
if (op == '<') {
return a < b
}
if (op == '>') {
return a > b
}
if (op == '==') {
return a == b
}
}; // var testApplyCompare = function () {
// ensure(applyCompare(["<", 1, 2]) === true, "applyCompare 1<2 错误");
// ensure(applyCompare(["<", 2, 1]) === false, "applyCompare 2<1 错误");
// ensure(applyCompare([">", 2, 1]) === true, "applyCompare 2>1 错误");
// ensure(applyCompare([">", 1, 2]) === false, "applyCompare 1>2 错误");
// ensure(applyCompare(["==", 1, 1]) === true, "applyCompare 1==1 错误");
// ensure(applyCompare(["==", 1, 2]) === false, "applyCompare 1==2 错误");
// };
// testApplyCompare();