一、初识函数
1.1:函数定义
函数用于封装完成一段特定功能的代码。
相当于将一条或者多条语句组成的代码块包裹起来。
用户在使用时,只需要关心参数和返回值,就能完成特定的功能,而不用了解具体的实现。
1.2:内置函数
如:
console.log(isNaN("number")); //true
console.log(parseInt("15.99")); //15
1.3:自定义函数
自定义函数提高代码的复用性,降低程序维护的难度
// 函数格式
// function name(params) {
// }
// function指这是一个函数语句
// name是函数名
// params是函数参数
// {}内放函数的具体功能
1.4:无参函数
// 封装函数
function demo() {
console.log("我是一个函数");
}
// 使用函数
demo()
1.5:有参函数
function sum(a,b) {
console.log(a+b);
}
sum(4,5)
1.6:函数的返回值
函数的返回值是指函数在调用后获得的数据
在定义函数时,可以为函数指定一个返回值,函数的返回值可以是任意类型的数据。
在JavaScript中使用return语句得到返回值并退出函数
{return 表达式}
function total01(price,num) {
var all=price*num;
return all
}
console.log(total01(999,12));
1.7:获取函数调用时传递所有实参
function num (a,b){
console.log(a,b);
}
num(1,2) //1,2
num(1,2,3,4,5,6,7) //1,2
num(1) //1 undefined
1.8:...扩展运算符
function num1(...nums) {
console.log(nums);
}
num1(1,2,3,4,5) //[1,2,3,4,5]
num1(1,2,3) //[1,2,3]
1.9:arguments对象
在开发时,如果不确定形参的个数,可以不设置形参
在函数体中直接通过arguments对象获取函数调用时传递的实参
function num2() {
console.log(arguments);
console.log(arguments.length);
}
num2(1,2,3,4,5)
结果:
二:函数内外变量的作用域
2.1:变量
2.1.1:全局变量
全局变量:在函数体外声明的变量或者在函数体内省略var关键字的变量
var a=10
function demo() {
console.log(a); // a为全局变量,在函数体内可以被访问。
c = 20
console.log(c); // c是省略var关键字声明的变量,为全局变量
}
demo()
console.log(a); // a为全局变量,在函数体外也可以被访问
console.log(c); // 可以在函数体外访问全局变量c
2.1.2:局部变量/函数变量
局部变量/函数变量:在函数体内利用let关键字声明的变量
function demo1() {
let b = 10
console.log(b); //b为函数体内用关键字声明,为局部变量
}
demo1() //10
console.log(b); //b is notdefined 不可以在函数外部访问局部变量b
2.1.3:块级变量
块级变量:在es6标准中,新增的let关键字声明变量为块级变量,一个花括号{}为一个块级。
if(true){
let sex = '男' //let声明变量sex为块级变量
console.log(sex); //块级变量sex可以在{}内部被访问
}
// console.log(sex); //块级变量sex不可在{}外被访问
注: [JavaScript三种作用域]
全局作用域:被全局变量所拥有:在{}外声明的变量
局部作用域:被局部变量所拥有:在函数内定义的变量
块级作用域:被块级变量所拥有:在分支语句或者循环大括号中定义的变量
2.1.4:变量提升
通过var声明的变量,在声明并赋值之前就能够访问到。
因为变量提升,所以1和2代码的执行效果一致
// 1
console.log(j); //undefined
var j=10;
// 2
var j;
console.log(j);
var j=10;
三:函数进阶
3.1:匿名函数
匿名函数:使用关键字声明后,函数可以不取函数名,直接使用声明的变量名。
var fn3=function (num1,num2){
console.log(num1+num2);
}
fn3(1,2) //3
3.2:箭头函数
箭头函数:删除function关键字,在参数与函数体中间放上“=>”
var fn4= (num1,num2)=>{
console.log(num1+num2);
}
fn4(1,2) //3
// 当函数体只有一句话时,可以省略大括号{}
var fn5= (num1,num2)=>console.log(num1+num2);
fn5(1,2) //3
// 当函数只有一句代码,并且函数的执行结果就是函数的返回值,
// 可以省略return关键字
var fn6=(num1,num2) => num1 + num2
console.log(fn6(1,2)); //3
// 当参数只有一个时,可以省略函数外部的小括号
var fn7= num1 => num1 + num1
console.log(fn7(1)); //2
四:回调函数
// 函数fn作为参数传递给参数cal
// 然后在函数cal中调用函数fn
// 此时,fn就是回调函数
function cal(num1,num2,fn) {
return fn(num1,num2)
}
console.log(cal(10,20,function(a,b){
return a+b
})); //30
在cal函数中设置了回调函数后,可以根据调用时传递不同的函数参数(相加函数,相乘函数),
去实现不同的功能,实现了函数的定制化。
五:定时器函数
5.1:setInterval()
"时间间隔"一到,代码就会执行一次。(反复执行)
表达式:
setInterval(function,time(毫秒))
如:
setInterval(function(){
console.log("该上课了");
},1000)
5.2:setTimeout()
用来指某个函数或某段代码在多少毫秒以后执行。(执行一次)
setTimeout(function(){
console.log("要抢票了");
},5000)
5.3:定时器函数特性
setTimeout指定的代码,必须等同步代码执行完毕后执行。
定时器函数属于异步代码。
console.log(1);
setTimeout(function(){
console.log(2);
},0)
console.log(3);
//1
//3
//2
六:函数嵌套与作用域链
6.1:函数嵌套
var i=10;
function fn1(){
var i=20;
function fn2(){
function fn3(){
console.log(i);
}
fn3()
}
fn2()
}
fn1() //20
6.2:变量访问规则:就近原则
当在一个作用域中访问变量时,首先看当前作用域有没有声明。
如果有则访问,没有则往上级作用域查找。
直到顶端作用域没有时,程序报错。
七:闭包函数
7.1:闭包函数
闭包(close):闭包是一种代码形式,内部函数访问外部函数的局部变量。
举例:JavaScript函数A中有一个函数B,函数B访问了函数A里面定义的局部变量,此时就产生了闭包。(变量所在的函数就是闭包函数,在这里,A就是闭包函数。)
// 外部函数
function A() {
// 外部函数定义的局部变量
let n = 10;
function B() {
// 内部函数要访问外部函数定义的局部变量
console.log(n);
}
B()
}
A() //10
7.2:闭包函数的作用
解决变量污染问题,让变量被函数保护起来。
在变量声明时,有些变量名十分常用, 为了避免和其他位置的代码起冲突,可以使用一个函数将代码包裹起来。
function fn(){
let count = 0;
setInterval(function(){
console.log(count++);
},1000)
}
八:递归函数
递归函数是一个函数间接或直接的调用自身
function getSum1(n){
// 当n=1时;
if(n==1){
return 1;
}
// 当前数组+比自己小1的数字
return n + getSum1(n-1)
}
console.log(getSum1(5)); //15