基础概念

声明

  1. //命令式声明
  2. function test() {
  3. //do something
  4. }
  5. 函数表达式(匿名函数)
  6. var func = function() {
  7. //do something
  8. }

特点

  1. 函数被看作一种特殊的值,如果函数体内没有返回值,获取到的值为undefined
  2. 函数提升

采用命令式声明时,函数定义的代码段会优先执行,因此函数声明可以写在函数调用之后

  1. f();
  2. function f() {}

采用函数表达式声明,函数调用在定义之前,解析器会报语法错误

  1. f();
  2. var f = function() {};
  3. //TypeError: undefined is not a function
  1. 同时采用function命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义

    1. var f = function() {}//只执行这行代码
    2. function f() {} //不执行
  2. 不允许在条件语句中声明函数(尽管解析器不会报错)

    1. if(true) {
    2. function a() {}
    3. }

参数

在javascript中,关于函数的参数有两类:
形参:函数定义时定义的参数
实参:要传入函数的参数

参数类型:其实就是指JS的数据类型,如 数字、字符串、布尔值、函数、函数返回值、对象、未定义
传递进去的是原始类型的数据(number , string, boolean),在函数内部修改不会影响外部变量
而传递进去的是复合类型的数据(array,object , function),由于传递进去的是地址,因此内部修改会影响外部变量。

  1. function add(a , b) {
  2. return a+b;
  3. }
  4. add(1,2);
  5. //a,b是形参,1和2 是实参

arguments对象

在函数的内部通过arguments对象获取参数的集合
arguments对象允许修改参数值,但是在严格模式下禁止操作

  1. var f = function(one) {
  2. console.log(arguments[0]); //1
  3. console.log(arguments[1]); //2
  4. console.log(arguments[2]); //3
  5. }
  6. f(1, 2, 3);


返回值

在函数体中通过return关键字返回函数的处理结果,可以是 字符串、数值、布尔值、函数、对象,而return后面的代码都不执行。

  1. function a() {
  2. return 1;
  3. }
  4. alert(a()); //弹出1
  5. function a() {
  6. return;
  7. }
  8. alert(a()); //弹出undefined;
  9. function a() {
  10. return 1;
  11. alert(123);
  12. }
  13. a(); //只弹出1,return后面的alert(123); 不执行

进阶知识

闭包

Function a() {
Var a; //b(),c()可见
Function b() {
Var b; //c()可见,a()不可见
Function c() {
Var c; //a(), b()不可见
链式作用域结构(chain scope)查找a变量时,先从b()开始,b()找不到,
再往上一层a()查找,a()找不到,在window对象下查找,找不到则报undefined;
}
}
}

闭包简单理解成“定义在一个函数内部的函数”,b和c都是闭包,是将函数内部和函数外部连接起来的一座桥梁。

两个作用点:
1、方便函数外部访问
2、常驻内存
3、用于封装私有属性和方法

缺点:每次调用都会产生新的内存消耗,会保留外层函数的内部变量

立即调用的函数表达式(IIFE)
(function() {
//do sth
}());
(function() {
//do sth
})();

Function() { …. }();
上述语句报错,原因:
1、function即可被当作关键字,又可以被当作表达式,上述代码定义会产生歧义
2、上述语句中,function被当成关键字,解析器当作函数定义,因此会被认为有语法错误