函数就是使用关键字 “function” 定义的一段具有独立作用域,能被反复执行的语句块,JavaScript函数大致包括普通函数、变量函数、构造函数、匿名函数、闭包函数以及ES6新增的箭头函数等。
1.函数定义
函数利用关键字**“function”**声明,其语法表现形式如下:
function function_name(arguments) {
// body...
}
function fun1() {
console.log('123');
}
上述代码中定义了一个函数,该函数的名字为**“fun1”,该函数没有设置参数,该函数的功能是打印输出一条语句,即“123”**。
2.函数调用
函数定义以后,并不会立即执行(自调函数除外,自调函数一旦创建,程序执行之后自调函数也会自动执行),因此要执行函数,需要调用函数,我们看下面这个实例。
function fun1() {
console.log('123');
}
fun1(); // "123"
上述代码定义函数之后,通过 fun1() 对函数进行调用,控制台输出*‘123’*,函数调用的形式为:function_name(argument),需要注意的是,即使没有参数,圆括号也不能省略。
3.函数的几种表现形式
3.1 普通函数
function sayHi() {
console.log('Hi');
} // this --> Window
sayHi() // Hi
3.2 变量函数
变量函数利用函数表达式进行声明:
var fun = function(argument) {
// body...
}
需要注意两点:
**1、**这样声明的函数,需要先声明后调用;
**2、**表达式内部的 function 无需再设置函数名,如果这样写,function后方的函数名只能被函数内部调用,在外部是无法使用的;
3.3 构造函数
function Person (name,age) {
this.name = name;
this.age = age;
this.sayName = function () {
alert(this.name);
}
}
var person = new Person('Alice','18'); //this-->person
person.sayName(); //'Alice'
注意两点:
**1、**构造函数内部会创建一个实例,调用普通函数时则不会创建新的对象。
**2、**构造函数内部的this指向是新创建的person实例,而普通函数内部的this指向调用函数的对象(如果没有对象调用,默认为window语句也是要作为字符串去呈现的,即需要给参数和函数体执行的代码都加上引号,否则会报“未定义”的错误。
3.4 匿名函数
匿名函数就是没有实际名字的函数。其表现形式如下
var b = function(){
console.log("hi")
};// this--> Window
b() //hi
匿名函数最大的特点就是没有名字。所以我们把他们称作“匿名函数”。然而,正因为他们没有“名字”,我们也没有办法找到他们。所以说我们就需要声明一个变量去调用它,还有一种可以调用的方式就是在函数后添加一个括号,让它立即调用。
3.5 闭包函数
代码如下:
function test() {
var str = "Hello, world!";
console.log(str);
} // this--> Window
test() //Hello,World
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
理解闭包可以看作是某种意义上的重生,但是需要付出非常多的努力和牺牲才能理解这个概念。要理解闭包,必须理解上下文环境和作用域的知识 。
4.自调函数
代码如下:
function(){
var a;
}()
等同于
!function(){
var a;
}();
自调用函数在程序执行之后也会自动执行,而且函数会变成函数表达式而不是函数声明,不加会被理解为函数声明,被前置处理掉。前面的!号可以换成- + ~等等一元操作符,从而省下了1字节。