回顾上章,我们讲了变量,顺便提到函数,讲了一些和函数相关的知识。这章着重给大家讲一下,函数。
什么是函数呢,这个我就不再说了。我只会讲平常用到的,比较重要的概念知识。
下来我们会讲到Function构造器、函数声明、函数表达式。这些都只是基础概念。应用层面的会比较广泛,比如闭包
Function构造函数
说起Function构造函数,可能许多人就要眨眨眉头了,其实你可以不用去理会,因为实践证明,构造函数式的函数在书写上,性能上都是不建议采取的。
构造函数式的创建函数也可分为三种:
方式一
var foo01 = new function() { var temp = 100; this.temp = 200; return temp + this.temp; }
上面这种方式好像是定一个函数。但是实际上这是定一个JavaScript中的用户自定义对象,不过这里是个匿名类。
这个用法和函数本身的使用基本没有任何关系,在大扩号中会构建一个变量作用域,this指代这个作用域本身。
方式二
var foo2 = new Function('var temp = 100; this.temp = 200; return temp + this.temp;');
仔细看这种方式和上一种方式的区别,一个是在()外部一个在内部。
这种系统内置函数对象来构建一个函数,这和利用函数表达式创建的方式在效果和初始化优先级上都完全相同,就是函数体以字符串形式给出。
方式三
var foo3 = Function('var temp = 100; this.temp = 200; return temp + this.temp;');
这种方式没有使用new来实例化,new还是很关键的,和原型就有关系了。但是不知道内置的这种函数内部机制是如何处理的。这种方式在书写还是正确的。
通过上面构造函数式可以看出,一个小小的Function有这么多玩法,但是这种方式虽然在性能上不值得我们采取,因为他们会new之后会分隔作用域,类似于eval。利用这种方式可以更好的理解后面我们学到的上下文this,下来我们来看看用到最多创建函数的方式,
函数表达式和函数声明
在ECMAScript中,创建函数最常用的方法就是函数表达式和函数声明。
函数声明:
function 函数名称 (参数:可选){ 函数体 }
函数表达式:
function 函数名称(可选)(参数:可选){ 函数体 }
这两种有什么区别呢,
其实最大的区别要算,函数声明会在进入上下文的时候,提前声明。函数表达式在代码执行期间才会进行声明处理。
函数表达式
这种方式是创建的常见方式之一,代码执行阶段创建,上代码
var foo= function(a,b){ return a + b; } console.log(foo(1,2));
该例演示是先创建了一个匿名函数然后赋值给变量foo,然后该函数可以用foo这个名称进行访问——foo()
同样函数表达式也可以拥有可选的名称:
var foo= function _foo(a,b){ return a + b; } console.log(foo(1,2));
这种方式和上面的有什么区别呢,外部的调用可以使用foo进行访问,而_foo则在外部不能使用,_foo只能在函数内部使用。
函数声明
function test(a,b){ return a + b; } console.log(test(1,2));
上面这种创建函数方式,和很多语言都很相似的,通过关键字直接声明,这种声明会被提前,
对于声明的级别,可以按以下顺序进行排列
函数的所有形参(如果我们是在函数执行上下文中)>>所有函数声明(FunctionDeclaration, FD)>>所有变量声明(var, VariableDeclaration)
对于声明这里就不多讲了。
下来我们讲一个重点,函数声明在源码中的位置:
// 函数可以在如下地方声明:// 1) 直接在全局上下文中function globalFD() { // 2) 或者在一个函数的函数体内 function innerFD() {}}
从上面的代码段可以看出,函声明只有这两个位置。也就是说:不可能在表达式位置或一个代码块中定义它。
我们讲解了2种重要的创建函数的方式,你会不会有疑问,我们为什么需要函数表达式?
答案很明显——在表达式中使用它们,”不会污染”变量对象。