函数就是使用关键字 “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 --> WindowsayHi() // 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--> Windowtest() //Hello,World复制代码
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
理解闭包可以看作是某种意义上的重生,但是需要付出非常多的努力和牺牲才能理解这个概念。要理解闭包,必须理解上下文环境和作用域的知识 。
4.自调函数
代码如下:
function(){ var a;}()等同于!function(){ var a;}();复制代码
自调用函数在程序执行之后也会自动执行,而且函数会变成函数表达式
而不是函数声明,不加会被理解为函数声明,被前置处理掉。前面的!
号可以换成- + ~
等等一元操作符,从而省下了1字节。