目录
函数
一个工具,被封装好可重复执行的一段代码块
-
系统函数: parseInt() alert() prompt() eval()
-
自定义函数:自己封装一段代码,需要的时候再调用
函数的声明和使用(两种方法):
//通过function关键字声明一个函数,跟上函数名,一对小括号,一对花括号,花括号里面放代码块
function test(){
//可重复执行的代码块
}
test();
test();
test();
//表达式定义法
var test1 = function(){
//可重复执行的代码块
}
for (var i = 0; i < 10; i++) {
test1();
}
函数和普通变量存储方式的区别
函数参数
形参:形式参数,声明函数的时候写在小括号里面的参数,无需var
实参:实际参数,在函数调用的时候需要传递实际有值得参数
实参个数大于形参,多余实参自动舍弃
形参个数大于实参,多余形参默认为undefined
实参副本arguments:可以在函数内部使用arguments接收所传递过来的参数,是一个集合
function test(){
console.log(arguments);
console.log(arguments.length);
}
test(1,2,3,5,6) // 打印 1,2,3,5,6 长度为5
作用域
变量的作用范围: 全局变量和局部变量
function fun(){
var a =0;
alert(a);
}
fun();
alert(a);
全局变量
作用范围为整个程序的执行范围
在函数体外部定义的变量就是全局变量
在函数体内部不使用var定义的也是全局变量
局部变量
作用范围是某个函数体内部
在函数体内部通过var关键字定义的变量或者形参,都是局部变量
当局部变量与全局变量重名时,在函数体内部局部变量优先于全局变量
return关键字
1.结束函数的执行
2.交回函数执行权
3.返回一个结果函数调用位置
堆栈
堆栈是一种数据结构,指的是数据存取的方式,当定义一个变量时,内存会开辟一段空间
栈( Stack):先进后出(FILO),在栈顶做插入(压栈)和删除操作(出栈)。
队列:先进先出(FIFO),在队头做删除操作,在队尾做插入操作。
堆和它们不同,代码执行时系统动态分配,不存在是先进后出还是先进先出。
执行环境执行栈(也称执行上下文–execution context)
当JavaScript解释器初始化执行代码时,它首先默认进入全局执行环境,从此刻开始,函数的每次调用都会创建一个新的执行环境,每一个执行环境都会创建一个新的环境对象压入栈中。
当执行流进入一个函数时,函数的环境对象就会被压入一个环境栈中(execution stack)。在函数执行完后,栈将其环境弹出,把控制权返回给之前的执行环境。
作用域链:
内层环境可以访问外层中的变量和函数,而外层环境不能访问内层的变量和函数
变量生命周期
全局变量的生命周期直至浏览器卸载页面才会结束。
局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量,直至函数结束
递归
程序调用自身的编程技巧称为递归( recursion)。
递归,就是在运行的过程中调用自己,本质就是循环。
构成递归需具备的条件
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。
由于递归是函数本身一层一层压栈,导致先入栈的不能出栈,空间占满以后就会造成堆栈溢出
斐波那契数列
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89........
这个数列从第3项开始,每一项都等于前两项之和。
在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>2,n∈N*)
函数练习题
1. 打印三行四列的表格
css:
table {
border: 1px solid #333;
border-collapse: collapse;
}
td {
border: 1px solid #333;
}
js:
function createTable () {
var str = '<table>'
for (var i = 0; i < 3; i++) {
str += '<tr>'
for (var j = 0; j < 4; j++) {
str += '<td>11</td>'
}
str += '</tr>'
}
str += '</table>'
document.write(str)
}
// 多次调用函数实现代码复用
createTable()
2. 编写一个函数,计算n ~ m之间的闰年(传参实现)
function leapYear (n, m) {
// 把n~m之间的所有闰年打印出来
for (var i = n; i <= m; i++) {
if (i % 4 === 0 && i % 100 != 0 || i % 400 === 0) {
console.log(i)
}
}
}
leapYear(1000, 2020)
3. 函数实现1-100中7的倍数或者带7的数(逢任何数字(通过传参)过)
function pass (n) {
for (var i = 1; i < 100; i++) {
var gw = i % 10
var sw = parseInt(i / 10)
// if (sw === n || gw === n || i % n === 0) {
// console.log('过')
// } else {
// console.log(i)
// }
if (sw === n || gw === n || i % n === 0) {
console.log('过')
continue
}
console.log(i)
}
}
pass(7)
4. 编写函数判断任意一个数是否是质数
function zhishu (n) {
var flag = true // 声明一个标志位,默认值为true,默认假设是质数
for (var i = 2; i < n; i++) {
if (n % i === 0) {
// 只要有任意一个被整除,说明默认值是错的,我们就把flag改为false
flag = false
break
}
}
// 如果flag仍然为true,说明在循环过程中一次if都没有成立,意味着一个能整除的都没有,那就是质数
if (flag) {
console.log(n + '是质数')
} else {
console.log(n + '不是质数')
}
}
zhishu(17)
5. 利用递归求100的阶乘
function jc (n) {
if (n === 1) return 1
return jc(n-1) * n
}
console.log(jc(100))
6. 函数和循环结合打印任意乘法表
function mulTable(n) {
for (var i = 1; i <= n; i++) {
for (var j = 1; j <= i; j++) {
document.write(j + "×" + i + '=' + i * j + " ");
}
document.write('<br>');
}
}
mulTable(9);
7. 编写函数实现:两个数平方的阶乘相加的和
要求:三个函数实现,一个求阶乘,一个求平方,第三个函数利用这两个函数求出最终结果
// 求平方
function sqrt(k) {
var s = k * k;
return s;
}
// 求jc n!
function jc(n) {
var num = 1;
for (var i = 1; i <= n; i++) {
num *= i;
}
return num;
}
// 求和
function add(a, b) {
// a的平方和b的平方
var a1 = sqrt(a);
var b1 = sqrt(b);
// a1的阶乘和b1的阶乘
var a2 = jc(a1);
var b2 = jc(b1);
// 相加
var sum = a2 + b2;
return sum;
}
console.log(add(2, 3));
8. 请列出m~n(m<n)的所有完全数
如果一个数恰好等于它的因数(除自身以外)之和,则称该数为“完全数” perfect number。
function perfectNum (m, n) {
for (var i = m; i <= n; i++) {
// 声明一个变量来累加i的所有因数
var sum = 0
// 通过循环找到i的所有因数
for (var j = 1; j < i; j++) {
// 判断j是否是i的因数
if (i % j === 0) {
sum += j
}
}
// 当所有因数加完了以后来判断是否相等
if (sum === i) {
console.log(i)
}
}
}
perfectNum(1, 10000)
9. 请编写一个函数,传入原文,输出密文
某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的
加密规则如下:
- 每位数字都加上5,然后用除以10的余数代替该数字
- 再将第一位和第四位交换,第二位和第三位交换
function jiami (num) {
var gw = (num % 10 + 5) % 10
var sw = (parseInt(num/10) % 10 + 5) % 10
var bw = (parseInt(num/100) % 10 + 5) % 10
var qw = (parseInt(num/1000) + 5) % 10
return '' + gw + sw + bw + qw
}