1、递归
function factorial(number) {
if (number == 1) {
return number;
}
else {
return number * factorial(number-1);
}
}
print(factorial(5));
当一个函数被递归调用,在递归没有完成时,函数的计算结果暂时被挂起。为了说明这个
过程,这里用一幅图展示了以 5 作为参数,调用 factorial() 函数时函数的执行过程:
5 * factorial(4)
5 * 4 * factorial(3)
5 * 4 * 3 * factorial(2)
5 * 4 * 3 * 2 * factorial(1)
5 * 4 * 3 * 2 * 1
5 * 4 * 3 * 2
5 * 4 * 6
5 * 24
120
2、定义和使用checking对象
function Checking(amount) {
this.balance = amount;
this.deposit = deposit;
this.withdraw = withdraw;
this.toString = toString;
}
function deposit(amount) {
this.balance += amount;
}
function withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
}
if (amount > this.balance) {
print("Insufficient funds");
}
}
function toString() {
return "Balance: " + this.balance;
}
var account = new Checking(500);
account.deposit(1000);
print(account.toString()); //Balance: 1500
account.withdraw(750);
print(account.toString()); // 余额:750
account.withdraw(800); // 显示 " 余额不足 "
print(account.toString()); // 余额:750
3、创建数组
最简单的方式是通过 [] 操作符声明一个数组变量:
var numbers = [];
使用这种方式创建数组,你将得到一个长度为 0 的空数组。可以通过调用内建的 length 属
性来验证这一点:
print(numbers.length); // 显示 0
另一种方式是在声明数组变量时,直接在 [] 操作符内放入一组元素:
var numbers = [1,2,3,4,5];
print(numbers.length); // 显示 5
还可以调用 Array 的构造函数创建数组:
var numbers = new Array();
print(numbers.length); // 显示 0
同样,可以为构造函数传入一组元素作为数组的初始值:
var numbers = new Array(1,2,3,4,5);
print(numbers.length); // 显示 5
最后,在调用 Array 的构造函数时,可以只传入一个参数,用来指定数组的长度:
var numbers = new Array(10);
print(numbers.length); // 显示 10
在脚本语言里很常见的一个特性是,数组中的元素不必是同一种数据类型,这一点和很多
编程语言不同,如下所示:
var objects = [1, "Joe", true, null];
可以调用 Array.isArray() 来判断一个对象是否是数组,如下所示:
var numbers = 3;
var arr = [7,4,1776];
print(Array.isArray(numbers)); // 显示 false
print(Array.isArray(arr)); // 显示 true
4、存取函数
JavaScript 提供了一组用来访问数组元素的函数,叫做存取函数
(1)、indexOf()
用来查找传进来的参数在目标数组中是否存在。
如果目标数组包含该参数,就返回该元素在数组中的索引;如果不包含,就返回 -1
var names = ["David", "Cynthia", "Raymond", "Clayton", "Jennifer"];
putstr("Enter a name to search for: ");
var name = readline();
var position = names.indexOf(name);
if (position >= 0) {
print("Found " + name + " at position " + position);
}
else {
print(name + " not found in array.");
}
如果数组中包含多个相同的元素, indexOf() 函数总是返回第一个与参数相同的元素的索引。有另外一个功能与之类似的函数: lastIndexOf() ,该函数返回相同元素中最后一个元
素的索引,如果没找到相同元素,则返回 -1
var names = ["David", "Mike", "Cynthia", "Raymond", "Clayton", "Mike", "Jennifer"];
var name = "Mike";
var firstPos = names.indexOf(name);
print("First found " + name + " at position " + firstPos);
var lastPos = names.lastIndexOf(name);
print("Last found " + name + " at position " + lastPos);
该程序的输出为:
First found Mike at position 1
Last found Mike at position 5
(2)、push、unshift、shift、pop、splice方法
(3)、排序reserve、sort,下面是排大小的例子
function compare(num1, num2) {
return num1 - num2;
}
var nums = [3,1,2,100,4,200];
nums.sort(compare);
print(nums); // 1,2,3,4,100,200
(4)、迭代器方法
这些方法对数组中的每个元素应用一个函数,可以返回一个
值、一组值或者一个新数组。
(01)、forEach
function square(num) {
print(num, num * num);
}
var nums = [1,2,3,4,5,6,7,8,9,10];
nums.forEach(square);
该程序的输出为:
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
(02)、every
另一个迭代器方法是 every() ,该方法接受一个返回值为布尔类型的函数,对数组中的每个元素使用该函数。如果对于所有的元素,该函数均返回 true ,则该方法返回 true 。下面
是一个例子:
function isEven(num) {
return num % 2 == 0;
}
var nums = [2,4,6,8,10];
var even = nums.every(isEven);
if (even) {
print("all numbers are even");
}
else {
print("not all numbers are even");
}
输出为:
all numbers are even
将数组改为:
var nums = [2,4,6,7,8,10];
输出为:
not all numbers are even
(03)、some
some() 方法也接受一个返回值为布尔类型的函数,只要有一个元素使得该函数返回 true ,
该方法就返回 true 。比如:
function isEven(num) {
return num % 2 == 0;
}
var nums = [1,2,3,4,5,6,7,8,9,10];
var someEven = nums.some(isEven);
if (someEven) {
print("some numbers are even");
}
else {
print("no numbers are even");
}
nums = [1,3,5,7,9];
someEven = nums.some(isEven);
if (someEven) {
print("some numbers are even");
}
else {
print("no numbers are even");
}
该程序的输出为:
some numbers are even
no numbers are even
(04)、reduce
reduce() 方法和 add() 函数一起,从左到右,依次对数组中的元素求和,其执行过程如下
所示:
add(1,2) -> 3
add(3,3) -> 6
add(6,4) -> 10
add(10,5) -> 15
add(15,6) -> 21
add(21,7) -> 28
add(28,8) -> 36
add(36,9) -> 45
add(45,10) -> 55
reduce() 方法也可以用来将数组中的元素连接成一个长的字符串:
function concat(accumulatedString, item) {
return accumulatedString + item;
}
var words = ["the ", "quick ","brown ", "fox "];
var sentence = words.reduce(concat);
print(sentence); // 显示 "the quick brown fox"
JavaScript 还提供了 reduceRight() 方法,和 reduce() 方法不同,它是从右到左执行。下面
的程序使用 reduceRight() 方法将数组中的元素进行翻转:
function concat(accumulatedString, item) {
return accumulatedString + item;
}
var words = ["the ", "quick ","brown ", "fox "];
var sentence = words.reduceRight(concat);
print(sentence); // 显示 "fox brown quick the"
(05)、 map() 和 filter()
有两个迭代器方法可以产生新数组: map() 和 filter() 。 map() 和 forEach() 有点儿像,对
数组中的每个元素使用某个函数。两者的区别是 map() 返回一个新的数组,该数组的元素
是对原有元素应用某个函数得到的结果。下面给出一个例子:
function curve(grade) {
return grade += 5;
}
var grades = [77, 65, 81, 92, 83];
var newgrades = grades.map(curve);
print(newgrades); // 82, 70, 86, 97, 88
下面是对一个字符串数组使用 map() 方法的例子:
function first(word) {
return word[0];
}
var words = ["for","your","information"];
var acronym = words.map(first);
print(acronym.join("")); // 显示 "fyi"
在上面这个例子中,数组 acronym 保存了数组 words 中每个元素的第一个字母。然而,如
果想将数组显示为真正的缩略形式,必须想办法除掉连接每个数组元素的逗号,如果直接
调用 toString() 方法,就会显示出这个逗号。使用 join() 方法,为其传入一个空字符串
作为参数,则可以帮助我们解决这个问题。
filter() 和 every() 类似,传入一个返回值为布尔类型的函数。和 every() 方法不同的是,
当对数组中的所有元素应用该函数,结果均为 true 时,该方法并不返回 true ,而是返回
一个新数组,该数组包含应用该函数后结果为 true 的元素。下面是一个例子:
function isEven(num) {
return num % 2 == 0;
}
function isOdd(num) {
return num % 2 != 0;
}
var nums = [];
for (var i = 0; i < 20; ++i) {
nums[i] = i+1;
}
var evens = nums.filter(isEven);
print("Even numbers: ");
print(evens);
var odds = nums.filter(isOdd);
print("Odd numbers: ");
print(odds);
该程序的执行结果如下:
Even numbers:
2,4,6,8,10,12,14,16,18,20
Odd numbers:
1,3,5,7,9,11,13,15,17,19
下面是另一个使用 filter() 方法的有趣案例:
function passing(num) {
return num >= 60;
}
var grades = [];
for (var i = 0; i < 20; ++i) {
grades[i] = Math.floor(Math.random() * 101);
}
var passGrades = grades.filter(passing);
print("All grades: );
print(grades);
print("Passing grades: ");
print(passGrades);
程序显示:
All grades:
39,43,89,19,46,54,48,5,13,31,27,95,62,64,35,75,79,88,73,74
Passing grades:
89,95,62,64,75,79,88,73,74
当然,还可以使用 filter() 方法过滤字符串数组,下面这个例子过滤掉了那些不包含
“cie”的单词:
function afterc(str) {
if (str.indexOf("cie") > -1) {
return true;
}
return false;
}
var words = ["recieve","deceive","percieve","deceit","concieve"];
var misspelled = words.filter(afterc);
print(misspelled); // 显示 recieve,percieve,concieve
计算平均成绩
var grades = [[89, 77, 78],[76, 82, 81],[91, 94, 89]];
var total = 0;
var average = 0.0;
for (var row = 0; row < grades.length; ++row) {
for (var col = 0; col < grades[row].length; ++col) {
total += grades[row][col];
}
average = total / grades[row].length;
print("Student " + parseInt(row+1) + " average: " +
average.toFixed(2));
total = 0;
average = 0.0;
}
内层循环由下面这个表达式控制:
col < grades[row].length
这个表达式之所以可行,是因为每一行都是一个数组,我们可以使用数组的 length 属性判
断每行包含多少列。
以下为程序的输出:
Student 1 average: 81.33
Student 2 average: 79.67
Student 3 average: 91.33