一、概念
函数就是封装了一段可以被重复执行调用的代码块 目的:就是让大量代码块重复使用
函数也是一种数据类型,引用数据类型。
第一种要求:不想打开页面而直接加载出结果,此处写一个函数,将代码放入函数中,在使用时调用函数即可
第二种要求,页面显示出来三个1-100的和,函数的重复调用,不会相互影响
二、函数的命名
1.建议名字以功能命名
命名规则 大驼峰 小驼峰
大驼峰—每个单词以大写开头
小驼峰—除第一个单词外,往后的每一个单词开头都是大写(常用
function 函数名(){
函数体
}
声明函数法二(匿名函数):var 变量名= function(){}
变量名是变量,存放的是函数表达式
<script>
1)命名函数
function fun(){
}
fun();
2)匿名函数 函数没有名字
function (){
}
(function(){
})();//调用
3)函数表达式形式
将一个匿名函数00赋值给一个变量
var myFun = function(a,b){
return a+b;
}
函数调用:
myFun();//变量名调用
</script>
(1)function是声明函数的关键字,全部小写
(2)函数是做某件事儿,函数名一般是动词
(3)函数不调用自己不执行
函数名();
函数调用的时候千万不要忘记加小括号
函数的参数:函数名字后面的括号里面的变量就是函数的参数,目的是在函数调用的时候,使用用户传过来的值进行操作,括号里面写了几个变量,即有几个参数,那么在函数调用时,给这些变量传值,也叫传参
形式参数
function 函数名(形参1,形参2…){
函数体
}
实际参数
函数名(实参1,实参2…);
<script>
//num1,num2就是形参
function getSum(num1,num2){
console.log('num1',num1);//undefined
var sum = num1 + num2;
// document.write(sum);
console.log(sum);
}
//函数的调用
// getSum(2,3);
//形参可以传入实际的值也可以传入变量
var a = 10;
var b = 20;
getSum(a,b);//可以称之为函数,也可以称之为实现加法的方法,函数的复用性,重复利用
</script>
多个参数之间要用逗号隔开,形参可以看做是不用声明的变量
我们给函数传的实参都会让函数自带的一个叫做arguments的对象给接收
arguments的使用,在我们不确定参数的数量,可以通过他来获取剩下的实参,对本身的形参并无影响
arguments[数组下标]
不确定会传入多少参数但是还想求和
<scrip>
function getSum(){
console.log(arguments);
//arguments里面的方法length,控制台中出现的length,表示长度
//函数复用性
var sum = 0;
for(var i= 0;i<arguments.length;i++){
sum +=arguments[i];
}
console.log('求和',sum);
}
getSum(10,20,30,40);
</scrip>
arguments是伪数组,伪数组并不是真正的数组,条件:1.具有数组的length属性2.按照索引的方式进行存储的3.没有真正数组的一些方法
法一:三元运算符
<scrip>
function getSum(a,b){//绝大多数是用来求1-100的和
var a = arguments[0]?arguments[0]:1;
//当函数里形参a没有接收到值,也就是说arguments[0]为undefined,所以三元运算符会把1,赋值给a
//当函数里形参a接收到值的情况下,arguments就是有值,所以根据三元运算符,会把arguments[0],将其值赋值给a
var b = arguments[1]?arguments[1]:100;
for(var i =a ;i<=b;i++){
sum+=i;
}
console.log(sum);
}
getSum(1,100);
</scrip>
法二:
<scritp>
function getSum(a=1,b=100){
var sum =0;
for(var i= a;i<=b;i++){
sum+=i;
}
console.log(sum);
}
getSum(100,200);
</scritp>
1)如果实参的个数多余形参的个数,会取到形参的个数
2)如果实参的个数小于形参的个数
形参可以看做不用声明的变量,多的形参是一个变量但是没有接受值,默认值就是undefined,结果就是 NaN
将函数值返回给调用者,此时通过return语句就可以实现,函数的默认值是undefined
格式:
function 函数名(){
函数体;
return需要返回的结果;
}
函数名();
(1)我们函数只是实现某种功能,最终结果需要返回函数的调用者函数名() 通过return实现的
(2)只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名()=return后面的结果
**注意事项:**return后面的代码不会被执行,return只能返回一个值,如果以逗号隔开,一最后一个值为准,如果想返回多个值,则可以使用数组
如果有return则返回return,如果没有则返回undefined
当函数名相同,参数列表不同,输入不同的参数,执行不同的操作
<script>
function f1(a,b){
console.log('我是第一个函数');
}
function f1(a,b,c){
console.log('我是第二个函数');
}
f1(10,20);//如果js支持重载函数,会找到第一个函数,但是js不支持函数重载,就是第二个
//js两个同名函数,后面的会覆盖前面的,前提是在同一作用域上
</script>
概念:代码(变量)可以使用的范围就是作用域,主要是为了提高程序的可靠性,也是为了减少命名冲突
全局作用域和局部作用域
全局作用域:指的是整个js文件,定义在全局中的全局变量,可以在局部作用域中使用,函数内部没有声明直接赋值的变量也叫全局变量
局部作用域:主要指的是函数作用域,函数的内部也就是局部作用域
在函数内部var定义的变量,叫做局部变量,局部变量无法被外部获取
通过作用域组成的作用域链:内部函数访问外部函数,采取的是连续查找的方式。来决定使用的是哪个变量
//就近原则
<script>
var a = 10;
function fn(){
// var a=20;
function fun (){
console.log('a',a);//20
//注掉函数体的a之后,答案是100
}
fun();
}
var a= 100;
fn();
</script>
js解析器:在运行js的时候,分两步。
第一步预解析:在解析过程中,会将声明变量或者声明函数进行提升,然后代码从上至下运行。
第二步执行代码:变量提升,定义变量时,变量的声明会被提升到作用域上,但是变量的赋值不会被提升
所有不用var声明的变量,程序会把它视作全局变量,不管你写在函数内还是函数外,也叫隐式转换
<script>
//函数提升
//js解析器 首先会把当前作用域的函数声明提升到整个作用域的最前面,注意:函数的变量提升比变量的的优先级高,函数提示将整个函数都提升上去
//先调用f1
f1();
var num =200;
function f1(){
var num = 20;
console.log("num",num);
}
var f2;
f2('你在');//会报错,因为此刻f1不是函数了
//程序的实际
//首先提升函数的内容--->其次提升变量var f1,直接执行变量f1里面的内容和函数,此刻a并没有获得值--->没有执行到这一步f1();
//匿名函数尽量避免函数提升
</script>
函数可以作为参数使用,只需要传入命名函数的名字
<script>
// 函数可以作为参数使用,只需要传入命名函数的名字
function f1(fn){
// console.log('fn',fn);
fn();//执行传过来的函数,我是f2
}
function f2(){
console.log('我是f2');
}
f1(f2);//调用f2
//像这种当做参数使用的函数也叫作回调函数
</script>
<script>
function f1(){
return function (){
console.log('我是返回函数');
//返回一个匿名函数
}
}
//有返回值就需要接收返回值
var ff = f1();
console.log(ff);//接收到的是这个匿名函数
ff();//返回匿名函数里面的函数体表达的内容
//一个函数的返回值也是函数,那他就是高阶函数
</script>