1.函数的三种定义方式
1.1.函数声明
function 函数名称() {
// 函数要执行的代码(要做的事情)
}
1.2.函数表达式
定义了一个变量,并将其初始化为一个函数,通过变量fn引用函数,另外,就像声明其他变量一样,使用函数表达式定义函数时,函数体外有分号。
var fn = function() {
// 函数执行代码
};
1.3.函数对象构造函数
Function构造函数可以接收任意数量的参数,最后一个参数为函数体,其他则为新函数的参数
var 变量名 = new Function("参数1","参数2",...,"参数n","函数体");
1.4.不同函数声明的区别
- 函数声明时,函数名必要,函数表达式中函数名可选
- 函数声明定义的函数,函数可以再函数声明之前调用;而函数表达式定义的函数只能在声明之后调用;解析器只有在读到函数表达式那一行时才被执行
- 构造函数是在对象被创建时调用,用于初始化且只执行一次,
2.函数三要素
- 函数名称
- 函数参数
- 函数返回值
3.匿名函数
没有函数名称的函数成为匿名函数,匿名函数不能单独存在
函数表达式的方式定义的函数就是匿名函数
var fn = function() {
}
tips:匿名函数只有在被调用时才能初始化,普通函数编译后函数声明和它的赋值都会被提前,所以普通函数的调用可以放在任意位置
4.自执行函数(沙箱函数)
需要调用者,在程序运行的时候,自己自动执行一次。并且只执行一次
//第一种写法
(function() {
alert('我是自己自动执行的');
})();
// 第二种写法
(function() {
alert('我还能这么做哦');
}());
5.构造函数中new关键字做的事
- new 构造函数的时候,在内存中创建一个空的对象
- 将构造函数中的this指向这个内存中的空对象
- 给对象添加属性和方法 对象身上就有了方法和属性
- 将这个有数据的对象返回回来
6.js参数的特殊情况
在js的函数中,对于传入参数的不确定的时候,可以使用arguments来接收传入参数数据, arguments是函数自带的一个容器,
function fn() {
// console.log(arguments); arguments 伪数组 具备数组的一些特点
for(var i=0;i<arguments.length;i++) {
console.log(arguments[i]);
}
// console.log(arguments);
}
fn(10,20,30,4,5,6);
如果定义的函数没有返回值,那么函数被调用时会返回它的默认返回值undefined
7.作用域和作用域链
- 全局作用域:在javascript标签的顶级,或者js外部文件的顶级,不能被函数包裹
- 局部作用域:被函数包裹,局部作用域内创建的变量叫局部变量
- 作用域链:变量生效的范围和查找规则 (函数内部优先访问局部变量,如果函数内部没有,就会忘上一层作用域查找,最终查找到全局作用域,如果全局作用域没有,就会报错)
注意:函数内的形参本质也是局部变量,函数形参只能在函数内访问,函数外部无法访问
8.js中的预解析
在javascript代码运行前,优先进行代码的预解析,预解析完成后,代码再从上往下执行
- var变量声明,创建变量的过程提升到作用域的最前面(只提升创建变量的过程,赋值的过程还在原位置)
- function函数声明,创建函数的过程中提升到作用域的最前面
- var的提升级别会比function高
例如,var num=8,js预解析为两部分:
// 声明变量,并提升到作用域的最前面。
var num;
// 在原位进行赋值
num = 18;