一、函数介绍
函数就是将实现特定功能的代码封装起来,当我们需要实现特定功能时,直接调用函数实现即可,不需要每次都写一堆代码,实现代码的复用。
函数的作用: 1、实现功能的封装,提高代码复用率 2、用于构建对象的模板(构造函数)
函数实际上是对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法,由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
二、函数的声明
语法:
function 函数名(形参列表){
//函数体
}
我们也可以写成函数表达式的形式:
var 函数名 = function(形参列表){
//函数体
}
例子:
function sum(a,b){
return a + b
}
//函数声明之后,需要调用才能执行
// 函数调用:函数名(实参)
console.log(sum(1,2)) //3
写成函数表达式的形式:
var sum = function(a,b){
return a + b
}
// 函数调用:函数名(实参)
console.log(sum(1,2)) //3
函数声明提升
函数声明与var声明的变量类似,也存在声明提升。
sum(1,2) //在此处调用函数不会报错,因为存在函数声明提升
function sum(a,b){
return a + b
}
注意:使用函数表达式声明函数时,不可以把函数调用写在函数声明前面,因为变量赋值不存在提升。
三、匿名函数
既然函数的定义跟变量的定义过程差不多,那函数的定义就可以像变量一样进行。
var f = function fn(){
console.log(12)
}
这是定义一个变量,将函数代码放到变量空间中,这样的函数也是可以正常进行调用的,就使用变量的名称就行:
f() // 12
那fn这个函数的名字还能进行调用吗:
fn() // fn is not defined
这样还是可以正常调用的:
f()
四、带返回值的函数
有的时候,我们会希望函数将值返回给调用者,此时通过使用 return 语句就可以实现。
return 语句的语法格式如下:
// 声明函数
function 函数名(){
...
return 需要返回的值;
}
// 调用函数
函数名(); // 此时调用函数就可以得到函数体内return 后面的值
- 在使用 return 语句时,函数会停止执行,并返回指定的值
- 如果函数没有 return ,返回的值是 undefined
有的时候,我们会希望函数将值返回给调用者,此时通过使用 return 语句就可以实现。
例如,声明了一个sum()函数,该函数的返回值为666,其代码如下:
// 声明函数
function sum(){
...
return 666;
}
// 调用函数
sum(); // 此时 sum 的值就等于666,因为 return 语句会把自身后面的值返回给调用者
五、预解析
预解析的相关概念
JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两 步:预解析和代码执行。
- 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提 前声明或者定义。
- 代码执行: 从上到下执行JS语句。
预解析会把变量和函数的声明在代码执行之前执行完成。
变量预解析
预解析也叫做变量、函数提升。
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
console.log(num); // 结果是多少?
var num = 10; // ?
结果:undefined
注意:**变量提升只提升声明,不提升赋值**
函数预解析
函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
fn();
function fn() {
console.log('打印');
}
结果:控制台打印字符串 --- ”打印“
注意:函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!
函数表达式声明函数问题
函数表达式创建函数,会执行变量提升,此时接收函数的变量名无法正确的调用:
fn();
var fn = function() {
console.log('想不到吧');
}
结果:报错提示 ”fn is not a function"
解释:该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之
前,此时fn的值是undefined,所以无法正确调用