一、概念
函数就是具备某个功能的一个工具。是完成某个功能的一段代码
二、函数
1.函数分为两种:(1)内置函数:js内部提供的
isNaN()、String()、Number()、alert()、confrim()
(2)自定义函数:自己定义自己使用
三、自定义函数语法
1.定义语法:function 函数名(){
重复执行的代码段
}
(1)function是一个关键字,函数名自定义,函数名的定义规则和变量是一样的,以数字、字母、下划线、美元符号、汉字命名,不能用数字开头,不能用关键字命名
(2)当我们定义好函数,并在页面中刷新的时候,会发现这段代码没有被执行。因为函数定义好之后,是不会自动执行的,需要我们进行调用。
2.函数的调用:
调用函数 --------- 让函数运行起来
(1)语法:
函数名() ------------- fn()
举例:九九乘法表
//九九乘法表常规写法
for(var a = 1; a <= 9; a++) {
for(var b = 1; b <= a; b++) {
document.write(b + '*' + a + '=' + a * b + ' ');
}
document.write('<br>');
}
//九九乘法表函数写法
function chengfabiao(num) {
for(var a = 1; a <= num; a++) {
for(var b = 1; b <= a; b++) {
document.write(b + '*' + a + '=' + a * b + ' ');
}
document.write('<br>');
}
}
chengfabiao(9)
chengfabiao(20)
chengfabiao(3)
四、函数的本质
1.定义函数
(1)就是在内存中开辟空间,将一段代码存储进去
(2)存储的值:一段函数代码
2. 存储的代码的数据类型:function
3.函数的本质
将函数理解为一个特殊的变量:
(1)数据:一段代码
(2)类型:function
(3)调用:让这段代码执行 ---- 函数名()
//函数定义在内存中的体现:
function fn(){
console.log(11)
}
//这段代码,在内存创建了一个空间,名字叫fn,这个空间中存储的数据是函数这整段代码。
//调用函数,就相当于将这段代码拿出来执行。
五、带参数的函数
1.(1)声明函数时候带进去的那个参数叫形参
(2)调用函数的时候给形参进行赋值的实际值是实参
(3)实参和形参是一一对应的
2.形参:形式上的参数 ---- 函数代码中会发生改变的值用变量来代替,在声明函数时的小括号内定义变量名 --------- 在函数内占位,准备使用
3.实参:实际上的参数 ---- 实参其实就是给形参赋值,让形参在函数内有具体的数据 --------- 隐藏的赋值过程
// 定义函数的时候,小括号中可以定义变量名,准备在函数中使用的变量 - 形参 - 形式上的参数
function fn(a, b) {
var c = a + b
console.log(c);
}
fn(2, 3) // 我们的目的是计算任意两个数字的和 ==> 每次调用函数都需要告诉函数我要计算哪两个数字的和
fn(3, 5) // 调用函数的时候,小括号中可以放入实际的值 - 实参 - 实际的值
六、函数返回值
1.关键字return
(1)理解方式一:正向
在函数中用 return 关键字,后面放一个具体数据 --- 在函数外调用函数的代码就能代表这个数据了
理解方式二:反向
在函数外调用函数的代码希望能代表一个具体数据 --- 需要在函数内 return 具体的数据
举例理解:
//不使用return
function add(a, b, c) {
var sum = a + b + c;
}
var avg = add(4, 5, 6) / 3;
console.log(avg);
/* 结果为NaN(代表一个非数字的数字类型) ,原因:除号有一边不是数字,也就是add(4,5,6)或者3
有一边不是数字,但是! 3肯定是数字,所以只能add(4,5,6)不是数字,此时我们就要解决让add(4,5,6)
变成一个具体的数字 */
//使用return返回结果
function add(a, b, c) {
var sum = a + b + c;
return sum;
}
var avg = add(4, 5, 6) / 3;
console.log(avg);
/* 如何让add(4,5,6)变成一个具体的数字呢? 首先, 看add(4,5,6)中的4,5,6只是我们给函数中
add(a,b,c)中的a,b,c赋的值, add(4, 5, 6)想要计算的方式是函数中sum = a+b+c ,也就是
和= 4+5+6
然后因为函数中 a+b+c的计算结果 赋给了 sum , 所以sum可以代表a+b+c, 因为add(4,5,6)是赋
值给(a,b,c)的, 所以 可以将add(4,5,6) 隐形的看做是一个sum , 让 这个隐形的sum 去进行函
数中的运算 ,然后再把结果 隐形的 返回给 add(4, 5, 6) ,
此时 ,就需要用到 function的关键字 return ,因为我是想让 隐形的sum参与计算并且将计算结果
返回给add(4, 5, 6) ,所以 我就要 return sum
让add(4,5,6)变成隐形的sum ,参与 函数的运算方式 (此时,为什么add(4,5,6)处不能直接写成
sum 呢? 因为外部函数不能调用内部函数的所有内容 ,但内部函数 可以调用外部函数 的所有内容)
*/
(2)return关键字除了可以给函数调用返回结果,还可以结束函数运行
举例:给函数调用返回结果
function fn() {
return 1,2 // 只能返回一个值,不能返回多个----结果为2
}
var num = fn()
console.log(num);
举例:结束函数运行
function fn() {
console.log(666);
return 888; // return可以结束函数,return后面的代码不执行的
console.log(777);
}
var num = fn()
console.log(num);
2.return总结:
(1)return可以给函数外部的调用返回一个结果
(1)结束函数执行
(2)函数运行后返回一个结果,只能返回一个
七、匿名函数
1.含义
函数是一种function类型,它的数据就是一段函数代码; 既然可以是数据,就可以将它赋值给一个变量使用; 赋值给变量后,这个变量名可以像函数名一样去使用这个函数,但是原本的函数名就无法使用了; 这种没有名字的函数就叫做匿名函数
2.用法
匿名函数如何使用?
(1)将他赋值给一个变量
(2)()括起来,后面再加() 表示这个函数定义好就立即调用 --- 立即执行函数/自调用函数
var a = function fn() {
console.log(666);
} // 将函数这段代码当做一个数据,就可以将他赋值给变量
console.log(a);
console.log(fn); // 将函数赋值给一个变量后,原本的名字就不能使用了
// 没有名字的函数叫匿名函数
var a = function(){
console.log(666);
}
console.log(a);
a()
// 匿名函数的使用,只能把它赋值给一个变量
var a = function() {
console.log(777);
}
a()
// 自调用函数 === 立即执行函数 :一个函数定义好就调用,且就调用这一次 - 不要名字
( function() {
console.log(777);
} ) ()
八、预解析
1.含义
1-1.代码在执行之前,会先进行解析
1-2.预解析具体在干嘛?
在所有的代码中找 变量的定义 和 函数的定义。找到了就将变量的定义代码和函数的
定义代码,提升放在所有代码的最前面。在执行的时候,按照解析后的代码进行执行。
1-3.浏览器执行js代码之前,会有一个预解析的过程:
浏览器中有一段程序专门用来解析js代码, 叫做js解析器。js解析器在执行js代码的时
候, 分两步进行:
(1)预解析js代码
预解析的过程,就是查找代码中的var和function这两个关键字,找到以后,
将变量和函数提前存到内存中,并给他们赋一个初始值,变量的初始值为
undefined,函数的初始值为代码段。
(2)开始按顺序一行一行解读代码
解读代码的时候,会略过变量和函数的定义,因为变量和函数的定义已经提
前放在内存中了,提前储存的变量和函数的值会随着代码的解读而发生变化,
也就是变量的赋值和函数的调用。
2.解析过程
会在所有代码中找 变量的定义 和 函数的定义,找到后将变量的定义和函数定义放在所有代码的最前面
3.预解析总结:
(1)当预解析的变量名和函数名同名,保留函数预解析,忽略变量预解析
因为函数预解析其实包含了赋值的过程,函数定义放在内存中的时候将函数的代码也放
在内存中
变量的预解析只有空间,没有值,所以如果是先预解析变量,那后面的函数预解析赋值
就将空间中放入了值,如果是先预解析的函数,再次预解析变量的时候,空间已经存在了,
再次定义空间也是没有意义的。
(2)只提升定义,不提升赋值
(3)函数定义会提升,变量赋值一个函数不会当做函数的提升
(4)js代码如果报错了,那后面的代码就不执行
(5)不会执行的代码中如果有变量或函数定义也会预解析,提升到前面,因为预解析在执行之
前。
练习题:
//第一题
fn()
function fn() {
console.log('我是一个 fn 函数')
}
fn()
var fn = 100
fn()
//第二题
var fn
function fn() {
console.log('我是一个 fn 函数')
}
fn()
fn()
fn = 100
fn()
//第三题
var fun = 200
fun()
var fun = function () {
console.log('我是一个 fun 函数')
}
fun()
//第四题
var fun
var fun
fun = 200
fun()
fun = function () {
console.log('我是一个 fun 函数')
}
fun()
//第五题
var a = b
a = 0
b = 0
console.log(a)
console.log(b)
//第六题
var a
a = b
a = 0
b = 0
console.log(a)
console.log(b)
//第七题
console.log(num)
if (false) {
var num = 100
}
//第八题
var num
console.log(num)
if (false) {
num = 100
}
九、函数嵌套
1. 注意:内部函数里可以调用外部函数,但是外部函数不可以调用内部函数
function fun() {
console.log(666);
}
function fn() {
// 代码段
/*
定义变量
运算
分支
循环
函数调用
定义函数
*/
fun()
}
fn()
十、函数的调试