JS基础-function函数部分
2019-02-21 本文已影响35人
壹枕星河
function
<script>
//封装函数(定义函数,声明函数)
function fn(){
//一段可重复执行的代码
alert(123);
}
//函数调用(函数名+小括号)
//fn();
var fn1 = function(){
alert(456);
}
fn1();
//匿名函数 立即执行函数 自调用函数
(function(){
alert(789);
})();
</script>
案例1 打印一个表格:
<script>
//打印三行四列表格
function createTable(){
var table = "<table>";
//拼接tr
for(var i = 0; i < 3; i++){
table += "<tr>";
//拼接td
for(var j = 0; j < 4; j++){
table += "<td>hello</td>";
}
table += "</tr>";
}
table += "</table>";
document.write(table);
}
createTable();
</script>
打印表格(参数版):
<script type="text/javascript">
function creatTable(row,col){
var table = "<table>";
for(var i = 0;i < row;i++){
table += "<tr>";
for(var j = 0;j < col;j++){
table += "<td>123</td>";
}
table += "</tr>";
}
table += "</table>";
document.write(table);
}
creatTable(4,5);
</script>
arguments
arguments是实参副本
<script>
//实参副本
/* function fn(){
console.log(arguments);
console.log(arguments.length);
}
fn(1,3);
function add(num1,num2){
console.log(num1+num2);
//索引(下标)从0开始
console.log(arguments[0]);
}
add(2,4); */
function addAll(){
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
}
console.log(sum);
}
addAll(2,10,20,453,32,324,34,34,34,3);
</script>
打印闰年:
console.log(n+"到"+m+"年的闰年有");
for(var i = n;i <= m;i++){
if(i%4 === 0 && i%100 != 0 || i%400 === 0){
console.log(i+"年");
}
}
}
year(1990,2019);
逢七过游戏:
for(var i = n;i <= m;i++){
if(parseInt(i)/10 === 7 || i%10 === 0 || i%7 === 0){
console.log("过");
}else{
console.log(i);
}
}
}
game7(1,50);
作用域
作用域:变量的作用范围
全局变量
1.作用范围为整个程序的执行范围
2.在函数体外部定义的变量就是全局变量
3.在函数体内部不使用var定义的也是全局变量
局部变量
1.作用范围是某个函数体内部
2.在函数体内部通过var关键字定义的变量或者形参,都是局部变量
3.当局部变量与全局变量重名时,在函数体内部局部变量优先于全局变量
变量提升
变量的声明会提升至当前作用域的最顶端,但不会提升赋值
返回值 return关键字
return关键字
1.结束函数的执行
2.交回函数执行权
3.返回一个结果到全局
堆栈
是一种数据结构,指的是数据存取的方式,当定义一个变量时,内存会开辟一段空间
栈( Stack):先进后出(FILO),在栈顶做插入(压栈)和删除操作(出栈)。
队列:先进先出(FIFO),在队头做删除操作,在队尾做插入操作。
堆和它们不同,代码执行时系统动态分配,不存在是先进后出还是先进先出。
作用域链
内层环境可以访问外层中的变量和函数,而外层环境不能访问内层的变量和函数
递归
程序调用自身的编程技巧称为递归( recursion)。递归,就是在运行的过程中调用自己,本质就是循环。
构成递归需具备的条件
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。
由于递归是函数本身一层一层压栈,导致先入栈的不能出栈,空间占满以后就会造成堆栈溢出。
菲薄拉契数列
<script>
//feb(0) === 1 feb(1) === 1
function feb(n){
//求数列的第n项的值
if(n === 0 || n === 1){
return 1;
}else{
return feb(n-1) + feb(n-2);
}
}
feb(5)
feb(4) + feb(3)
feb(3) + feb(2) + feb(2) + feb(1)
feb(2) + feb(1) + feb(1) + feb(0) + feb(1) + feb(0) + feb(1)
feb(1) + feb(0) + feb(1) + feb(1) + feb(0) + feb(1) + feb(0) + feb(1)
</script>
JS运行和编译
- 语法分析
查找基本语法有没有错误 - 预解析
执行之前进行预解析
var、function关键字提前到当前作用域的顶部,变量默认值为undefined,函数默认值为函数体代码块,当函数与变量重名时,保留函数。 - 解释执行
变量生命周期
- 全局变量的生命周期直至浏览器卸载页面才会结束。
- 局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量,直至函数结束
变量提升
会把当前作用域声明的变量提升到作用域的顶部,但是不会提升赋值。
当全局变量和局部变量重名时,局部变量的优先级更高。
//预编译
/* console.log(a);
var a = 10; //变量提升
console.log(a); */
/* 提升之后的结果
var a;
console.log(a);
a = 10; */
/* var b = 10;
function foo(){
console.log(b);
var b = 20;
}
foo(); */
/* 提升之后的结果
var b = 10;
function foo(){
var b;
console.log(b);
b = 20;
}
foo(); */
函数提升(包括函数体一块提升)
和变量提升类似。在提升时变量和函数都会提升,当变量和函数同名时会保留函数。
/* bar();
function bar(){
alert(123);
} */
//通过function关键字申明的函数会连着函数体一块提升到当前作用域顶部
//但是通过变量名赋值为一个匿名函数的方式申明的函数,只会提升变量的申明,函数体不会提升
/* bar();
var bar = function(){
alert(456);
} */
/* 提升之后的,会报错
var bar;
bar();
bar = function(){
alert(456);
} */
案例:
//1、编写一个函数,计算n ~ m之间的闰年(传参实现)
function leapYear(n,m){
for(var i = n; i <= m; i++){
if(i%4 === 0 && i%100 != 0 || i%400 === 0){
console.log(i);
}
}
}
//leapYear(2000,2020);
//2、编写函数计算任意数字的阶乘(两种方法)
function jiecheng(n){
//for
/*
var result = 1;
for(var i = 1; i <=n; i++){
result *= i;
}
return result;
*/
//递归
if(n === 1){
return 1;
}else{
return jiecheng(n-1) * n;
}
//return n === 1 ? 1 : jiecheng(n-1) * n;
}
//console.log(jiecheng(4));
//3、编写函数实现:两个数平方的阶乘相加的和
//要求:三个函数实现,一个求阶乘,一个求平方,
//第三个函数利用这两个函数求出最终结果
function pow(n){
return n*n;
}
function fn(a,b){
return jiecheng(pow(a)) + jiecheng(pow(b));
}
//console.log(fn(1,2));
//4、如果一个数恰好等于它的因数之和,则称该数为“完全数” perfect number。(包含1不包含本身)
//请列出2~10000的所有完全数(要求用两个函数实现)
function isPerfect(n){
//从1开始,到n-1找到所有因数并相加
var sum = 0;
for(var i = 1; i < n; i++){
//n能不能i被整除
if(n%i === 0){
sum += i;
}
}
//判断sum和n是否相等
/* if(sum === n){
return true;
}else{
return false;
} */
// return n === sum ? true : false;
return n === sum;
}
//输出a-b中间的左右完全数
function fn1(a, b){
for(var i = a; i <= b; i++){
//判断i是否是完全数
if(isPerfect(i)){
console.log(i+"是完全数");
}
}
}
fn1(2,1000);
//每位数字都加上5,然后用除以10的余数代替该数字,
//再将第一位和第四位交换,第二位和第三位交换
function secret(num){
//把num的每一位数字取出来
var ge = (num%10+5)%10,
shi = (parseInt(num/10)%10+5)%10,
bai = (parseInt(num/100)%10+5)%10,
qian = (parseInt(num/1000)+5)%10;
/* var temp = ge;
ge = qian;
qian = temp; */
//不用第三个变量完成两两交换(只适用于两个数字交换)
/* ge = ge + qian;
qian = ge - qian;
ge = ge - qian; */
//return ge*1000 + shi*100 + bai*10 + qian;
//return String(ge) + shi + bai + qian;
return "" + ge + shi + bai + qian;
}
console.log(secret(5555));
</script>