一、函数定义
1.方式一 function 函数名(参数){ 函数体 }——————函数声明的方法
function fn(a){
console.log(a);
};
2.方式二 var 变量名 = function(参数){ 函数体 }——————函数表达式
var fn=function(a){
console.log(a);
};
3.注意的问题:
- 函数必须先定义,再调用
//先声明
function fn(a){
console.log(a);
}
//调用函数
fn(1);
- 函数最好一个功能一个函数
- 函数推荐使用驼峰式命名
function getMax(a,b){
if(a<b){
console.log(b);
}else{
console.log(a);
}
};
getMax(2,3);//3
- 有名字的函数称为命名函数;反之,没有名字的函数称为匿名函数
- 方式二定义的函数称为函数表达式,把一个函数给一个变量,调用函数用 变量名(参数)
- 函数表达式声明的函数后面要加分号
- 区别:函数声明的方法重名会覆盖,函数表达式相当于变量的再赋值
function f1(){
console.log("我是第一个函数");
};
function f1(){
console.log("我是第二个函数,我覆盖了第一个函数")
};
f1();//我是第二个函数,我覆盖了第一个函数
var f2=function(){
console.log("我是第一个函数")
};
f2=function(){
console.log("我是第二个函数")
};
f2();//我是第二个函数
- 函数的自调用,没有名字,调用------声明的同时,一次性的
fn=function(){
console.log("函数fn代表整个函数代码,后面加括号就是调用");
}();//会输出内容,相当于fn()的调用,简写版
二、参数
1.形参:函数定义的时候,小括号里面的变量
2.实参:函数再调用的时候,小括号里面的变量或者值
//声明定义函数的时候,a和b就是形参
function getMax(a,b){
if(a<b){
console.log(b);
}else{
console.log(a);
}
}
//调用函数的时候,传入的值,2和3就是实参
getMax(2,3);//3
3.形参个数和实参个数可以不一致
function getMax(a,b,c){
if(a<b){
console.log(b);
}else{
console.log(a);
}
}
getMax(2);//当传入的是一个值得时候,输出就是第一个参数a的值2
getMax(2,3);//形参多于实参,输出依然是3
getMax(2,3,4,5);//实参多于形参,输出也是3
三、return返回
1.return后面有内容,这个内容被返回了
function getSum(a,b){
return a+b;
};
console.log(getSum(2,3));//5
2.类型:有参数有返回值/没有返回值,没有参数有返回值/没有返回值
常用:
//有参数有返回值
function getSum(a,b){
return a+b;
};
console.log(getSum(3,4))//7
//有参数没有返回值
function sayHi(a){
console.log("这是我输入的语句:"+ a +"!")
};
sayHi("今天天气真好");//这是我输入的语句:今天天气真好!
3.函数没有返回值,但是接收了,结果是undefined
function getSum(a,b){
var c=a+b;
}
console.log(getSum(2,4));//undefined
4.没有明确的返回值,即return后面没有内容,结果也是undefined
function getSum(a,b){
var c=a+b;
return;
}
console.log(getSum(2,4));//undefined
5.return后面的代码不会执行
function getSum(a,b){
var c=a+b;
return c;
console.log("我在return的后面,不会执行了");
};
console.log(getSum(2,4));//6
6.有return最好设置定义一个变量去接受它,接收后这个变量就可以去进行其他操作,或者输出,或者进行运算等等
function getSum(a,b){
return a+b; ;
}
var result=getSum(10,20);
console.log(result); //30
四、变量
1.全局变量:
- 声明的变量使用var声明,可以在页面的任何位置使用
- 除了函数以外,其他位置的变量都是全局变量
- 全局变量如果页面不关闭,就不会释放,站空间内存
var a=1;//全局变量
for(var b=2;b<2;b++){
//全局变量
console.log("哈哈");
}
function f1(){
var c=1;//不是全局变量
};
console.log(a);//1
console.log(b);//2
console.log(c);//报错
2.隐式全局变量
- 声明的变量没有var 声明
- 隐式全局变量使用delete可以删除
- 全局变量使用delete不能删除
var a=10;//显式声明的全局变量
b=20;//隐式声明的全局变量
console.log(a);//10
console.log(b);//20
delete a;
delete b;
console.log(a);//10(依然可以输出,说明delete无效)
console.log(b);//报错
console.log(typeof(b));//undefined
3.局部变量
- 在函数内部定义的变量,外面不能使用
function f1(){ var c=1;//局部变量 console.log(c); }; f1();//1 console.log(c);//报错
4.全局作用域和局部作用域
- 全局作用域就是全局变量的使用范围
- 局部作用域就是局部变量的使用范围
5.作用域链
- 函数变量是从本作用域开始寻找,从里到外
var a=10;
function f1(){
var a=20;
var b=a+a;
return b;
};
console.log(f1());//40
- 示意图
五、预解析
-
理解:在解析代码之前做的事,把变量的声明和函数的声明提前到当前所在作用域的最前面。
-
步骤:
- 把变量的声明提升到当前作用域的最前面,只提升声明,不会提升赋值
- 把函数的声明提升到当前作用域的最前面,只提升声明,不会提升调用
- 先提升var ,再提升function
//正常代码,没有预解析之前
f1();//前端good!
function f1(){
var a="good!";
console.log("前端"+a);
};
console.log(b);//undefined
var b=10;
//上面的代码通过预解析之后会变成下面这样
var b;//var 变量声明提前
function f1(){
var a;//函数的声明提前,在当前作用域的最前面
a="good!";
console.log("前端"+a);
};//函数的声明提前
f1();
console.log(b);
b=10;
-
只有用函数声明方式定义的函数才会提升function,函数表达式定义的函数是一个变量,提升var
f1();//报错,因为预解析只提升了var f1;到上面
var f1=function(){
console.log("前端")
};
-
变量和函数重名,执行函数(表达不准确,主要看代码)
var a;
function a(){
console.log("前端大法好");
};
console.log(a);//输出上面的a函数,而不是undefined
a=10;
console.log(a);//10
-
如果有多对的script标签都有相同的名字的函数,
①如果函数是通过声明定义的,不会受影响
<script>
function a(){
console.log("哈哈")
};
</script>
<script>
a();//嘿嘿
function a(){
console.log("嘿嘿")
};//函数声明会提前
</script>
②如果函数是通过函数表达式声明的,会受影响
<script>
var a=function(){
console.log("哈哈")
};
</script>
<script>
a();//哈哈
var a=function(){
console.log("嘿嘿")
};
</script>
六、总结
1.argument
- 当做数组使用,是一种伪数组
- argument.length可以获取函数在调用传入的个数
function howManyArgs() {
console.log(arguments.length);
};
howManyArgs("string", 45);//2
howManyArgs();//0
howManyArgs(12);//1
- 使用argument[ " " ] 对象可以获取传入的每个参数的值
function f1(a,b,c,d) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
console.log(arguments[3]);
console.log(arguments[4]);
};
f1(1,2,3,4);//1 2 3 4 undefined
2.函数也是一种数据类型
- typeof检测出来的类型是function
function f1() {
console.log("good!");
};
var f2 = function () {
console.log("nice");
};
console.log(typeof(f1)); //function
console.log(typeof(f2));//function
3.函数参数的类型
- 函数参数的数据类型可以是数字、字符串、布尔、数组等等
function f1(a){
console.log(a);
};
f1(10);//参数是number
f1("嘿嘿");//参数是string
f1(1===2);//参数是Boolean
f1([10,20,30,40]);//参数是Array
var i=null;
f1(i);//参数是null
var j;
f1(j);//参数是undefined
- 函数也可以作为参数使用,如果一个函数作为参数,那么这个参数(函数)就是回调函数
- 只要看到一个函数作为参数使用,就是回调函数
function f1(fn){
console.log("我是f1");
fn();
}
function f2(){
console.log("我是f2");
}
f1(f2);//我是f1 我是f2
//注意:是f1(f2),而不是f1(f2())
4.函数可以作为返回值使用
function f1(){
console.log("我是f1");
return function f2(){
console.log("我是f2");
}
}
f1();//我是f1
var ff=f1();//理解f1()是函数f1里面执行的内容,而f1是这个函数的整个表达式,定义一个变量去接受这个函数的调用
ff();//我是f1 我是f2
七、函数案列
//例1:m-n之间所有数的和
function getSum(m,n){
var sum=0;
for(var i=m;i<=n;i++){
sum=sum+i;
}
return sum;
}
var result=getSum(1,100);
console.log(result);//5050
//例2:圆的面积
function area(r){
return Math.PI*r*r
}
var result=area(3);
console.log(result);//28.274333882308138
//例3:判断一个数是不是质数;
function prime(num){
if(num==2){
return true;
}
for(var i=2;i<num;i++){
if(num%i!==0){
return true;
}else{
return false;
}
}
}
var result=prime(6);
console.log(result);//flase
//例4:两个数的最大值
function getMax(a,b){
return a>b?a:b
}
var result=getMax(2,3);
console.log(result);//3
//例5:三个数的最大值
function getMax(a,b,c){
return a>b?(a>c?a:c):(b>c?b:c);
}
var result=getMax(2,5,4);
console.log(result);//5
//例6:两个数的差
function differ(a,b){
return a-b;
}
var result=differ(6,3);
console.log(result);//3
//例7:一组数中的最大值
function getArrayMax(arr){
var max=arr[0];
for(var i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
var arr=[1,2,3,4,5];
var result=getArrayMax(arr);
console.log(result);//5
//例8:一组数字的和
function getSum(arr){
var sum=0;
for(var i=0;i<arr.length;i++){
sum=sum+arr[i];
}
return sum;
}
var arr=[1,2,3,4,5];
var result=getSum(arr);
console.log(result);//15
//例9:数组反转
function rev(arr){
for(i=0;i<arr.length/2;i++){
var temp=arr[i];
arr[i]=arr[arr.length-1-i];
arr[arr.length-1-i]=temp;
}
return arr;
}
console.log(rev([1,2,3,4,5]));//(5) [5, 4, 3, 2, 1]
//例10:冒泡排序(从大到小)
function pup(arr){
for(var i=0;i<arr.length-1;i++)
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]<arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
return arr;
}
console.log(pup([1,5,3,7,4,9]))//(6) [9, 7, 5, 4, 3, 1]
//例11:阶乘和
function floor(num){
var sum=1;
for(var i=1;i<=num;i++){
sum=sum*i
}
return sum;
}
var result=floor(5);
console.log(result);//120
//例12:菲波那契数列
function rab(num){
num1=1;
num2=1;
sum=0;
if(num==1||num==2){
sum=1;
}
for(var i=3;i<=num;i++){
sum=num1+num2;
num1=num2;
num2=sum;
}
return sum;
}
var result=rab(12);
console.log(result);//144
//输入年月日,返回是这一年的第几天
function getDays(year, mouth, day) {
var days = day;
//如果月份是1月,直接返回天数
if (mouth == 1) {
return days;
}
//如果月份是其他月,先定义数组,循环月份求和
var mouths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for (i = 0; i < mouth - 1; i++) {
days = days + mouths[i];
}
//判断这一年是不是闰年,并且如果月份大于2,多一天
if (year % 4 == 0 && year % 100 !== 0 && mouth >= 2 || year % 400 == 0 && mouth >= 2) {
days++;
}
return days;
}
var result = getDays(2018, 4, 25);
console.log(result);//115
来源:oschina
链接:https://my.oschina.net/u/4407434/blog/4043287