函数是一段可以重复使用的代码段
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,起个名字(函数名),在后续开发中可以反复调用。
函数的作用就是封装一段代码,将来可以重复使用。
定义函数
function 函数名(){
函数体 - 需要重复时候用的代码
}
function tellStory() {
console.log('从前有座山,山上有座庙');
console.log('庙里有个老和尚和一个小和尚');
console.log('老和尚正在给小和尚讲故事');
console.log('讲的什么呢?');
}
注意点: 函数里面的代码是不会执行的,需要调用才会执行
函数的调用:
然而我们写出上面函数的代码之后,在浏览器中打开页面,
却没有任务内容被输出。这是因为函数在定义的时候,
里面的代码是不会执行的,只有调用了函数,函数中的代码才会执行。
tellStory()//函数名();
每调用一次,就会执行一次,做了代码的重复使用。
一定要记住,函数定义时是不会执行的,只有调用时才会执行。
可以使用代码调试工具进行代码执行过程观察。
函数的参数
重复使用函数的过程会有变化的值,就可以用参数解决
语法:
function 函数名(参数){
函数体
}
function fn(n){
console.log(n)//此时n的内容是 函数体
}
fn(函数体)
就是说参数就好像函数里面的一个变量一样,可以存储一个随时变量的数据
当我们调用函数的时候,再给一个真实的值
函数的参数可以一个,也可以是多个,只要在重复的过程中,有多个会产生变化的数据,都可以使用参数的方式解决
在定义函数时写的占位用的参数,我们称为形参,在调用函数,实际参与函数执行的参数,我们称为实参
函数的返回值
函数执行完毕之后会有一个执行结果,该结果就叫 —— 返回值
如果你希望函数执行完毕之后,有一个你想要的数据,就可以使用返回值来实现
函数默认情况下,得到的结果是 —— undefined
想要修改可以修改,使用return修改
函数体没有写return 在函数外是访问不了的
函数体写了return 就会得到return 后面需要返回的内容
return 跳出函数, 下面的代码不会继续执行
补充函数
函数表达式
var 函数名 = function(参数){
函数体
}
var getSum = function(a,b){
return a + b;
}
匿名函数
没有名字的函数
function (参数){ 函数体 }
自调用函数
(function({
// 写一些为了避免变量污染的代码
}))();
全局和局部作用域
作用域
var a = 10;
function f1(){
console.log(a);
}
f1();// 变量a在函数外定义,可以在函数内使用
function f2(){
var b = 20;
}
console.log(b); // 变量b在函数内定义,在函数外无法访问,报错: b is not defined
这是因为js中存在作用域的概念。
作用域:
作用域就是指定一个变量或者一个函数的作用范围。
能在页面的任何位置都可以访问,称为 全局作用域
只能在函数内访问,称为为 局部作用域
在全局作用域下声明的变量,称为 全局变量
在局部作用域下声明的变量,称为 局部变量
上述代码中,a是全局变量,b是局部变量
全局
script标签或者是一个js文件内部直接定义的
在全局下定义的变量在任何位置都可以使用,称为全局变量
局部
函数内部就是局部作用域
function fn(){
var b = 10; // b就是局部变量
}
局部作用域里面的数据,外面是访问不了的。
作用域的作用就是为了把数据进行保护,不让外部的数据对我们的数据进行污染
作用域链
在JavaScript里面,函数内部是可以包含另一个函数的
function a(){
function b(){
}
}
此时函数b就被函数a包含越来了,这样就形成了两层作用域。
预解析
因为在js中,代码执行之前,会先进行一次预解析
预解析就是在执行代码之前,把代码中的变量声明和函数声明,提升到当前作用域的最顶端,而变量的赋值和函数的调用还在原来的位置。
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
//以上代码预解析
function f1() {
var a
a = 9
b = 9 //没有声明的值是全局的
c = 9;//没有声明的值是全局的
console.log(a); 9
console.log(b);9
console.log(c);9
}
f1();
console.log(c); 9
console.log(b); 9
console.log(a); //报错获取不了局部的
arguments
我们求三个数的和可以调用求两个数的和的函数,那么要求四个数的和也调用求三个数的和的函数,这样如果要求n个数的和,就要写n-1个函数了,这样是很麻烦的
在js中,函数的实参和形参的个数是允许不同的
function fn(a,b){
return a + b;
}
fn(1,2,3,4);// 正常执行,不会报错
但是我们如果得到在实参里多出的3和4呢?js里面提供了一个在函数中专用的,获取所有实参的对象:arguments
function fn(){
console.log(arguments);
}
fn(1); // 输出 [1]
fn(1,2) // 输出 [1,2]
fn(1,2,3,4,5) // 输出 [1,2,3,4,5]
arguments 这个东西看起来像数组,但是其实不是一个数组,我们管它叫 伪数组
。它具有数组的长度和顺序等特征。
arguments这个东西就解决了我们要求n个数字的和的问题
function getSum(){
var sum = 0;
for(var i = 0; i < arguments.length ; i++){
sum += arguments[i];
}
return sum;
}
getSum(1,2,3);// 输出 6
getSum(1,2,3,4,5); // 输出15