js函数声明和函数表达式的区别

JavaScript06

js函数声明和函数表达式的区别,第1张

上述两种方式除了定义的语法不同之外,最主要的区别是函数声明具有【函数声明提升】的特点,将函数声明提升到作用域顶端,意思是在执行代码之前会先读取函数声明,也就是说可以把函数声明放在函数调用的后面。

例子1:

test()//弹出hello,因为【函数声明提升】的特点,函数调用之前,已经读取了该函数完成了声明

            function test(){

                alert("hello")

            }

例子2:

 test()//报错:Uncaught ReferenceError: test is not defined

            //因为【函数表达式】不具备提升的特点,在函数调用时,作用域中还未读取该函数的定义

            //作用域读取函数表达式是按照代码顺序读取

            var test = function(){

                alert("hello")

            }

            test()//弹出hello

例子3:

            if(condition){

                function test(){

                    alert("hello")

                }

            }else{

                function test(){

                    alert("world")

                }

            }

            //弹出world,因为函数声明在代码执行前就已经完成了,作用域已经完成了对该函数的读取,与条件无关

            //同名函数声明,后面的会覆盖前面的

            test()

            if(condition){

                var test2 = function(){

                    alert("hello")

                }

            }else{

                var test2 = function(){

                    alert("world")

                }

            }

            //弹出内容与条件相关,作用域读取函数表达式是按照代码执行顺序读取的

            test2()

例子4:

 //函数表达式

            var  test = function(){

                alert("hello")

            }

            //第一次调用

            test()

            //变量声明

            var s = "world"

            //函数声明

            function test(){

                alert(s)

            }

            //第二次调用

            test()

        //解释:两次调用都将弹出hello,在代码执行前方式二已经被作用域读取,然后执行方式一代码,方式一的test覆盖方式二的test,然后执行两次调用弹出hello

1:调用关键字function来构造

function distance(x1,x2,y1,y2)

 {

 var dx=x2-x1

 var dy=y2-y1

 return Math.sqrt(dx*dx+dy*dy)

 }

2:使用Function()构造函数(请注意与上面的大小写)

1

var f=new Function*"x","y","return x*y")

这行代码创建了一个新函数,该函数和你所熟悉的语法定义的函数基本上时等价的:

1

2

3

4

function f(x,y)

{

    return x*y

}

Functino()构造函数可以接受任意多个字符串参数。它的最后一个参数时函数的主体,其中可以包含任何JavaScript语句,语句之间用分号分隔。其他的参数都是用来说明函数要定义的形式参数名的字符串。如果你定义的函数没有参数,那么可以只需给构造函数传递一个字符串(即函数的主体)即可。 

注意,传递给构造函数Function()的参数中没有一个用于说明它要创建的函数名。用Function()构造函数创建的未命名函数有时被成为“匿名函数”。 

你可能非常想知道Function()构造函数的用途是什么。为什么不能只用function语句来定义所有的函数呢?原因是Function()构造函数允许我们动态地建立和编译一个函数,它不会将我们限制在function语句预编译的函数体中。这样做带来的负面影响效应就是每次调用一个函数时,Function()构造函数都要对它进行编译。因此,在循环体中或者在经常使用的函数中,我们不应该频繁地调用这个构造函数。 

使用Function()构造函数的另一个原因是它能够将函数定义为JavaScript表达式的一部分,而不是将其定义一个语句,这种情况下使用它就显得比较的方面,甚至可以说精致。

 3:函数直接量 

函数直接量是一个表达式,它可以定义匿名函数。函数直接量的语法和function语句非常相似,只不过它被用作表达式,而不是用作语句,而且也无需指定函数名。下面的三行代码分别使用function()语句、Funciont()构造函数和函数直接量定义了三个基本上相同的函数:

1

2

3

function f(x){return x*x}

 var f=new Function("x","return x*x")

 var f=function(x){reurn x*x}

在JavaScript1.1中,可以使用构造函数Function()来定义函数,在JavaScript1.2和其后的版本中,还可以使用函数直接量来构造函数。你应该注意这两种方法之间的重要差别。 

 

首先,构造函数Function()允许在运行时动态地创建和编译JavaScript代码。但是函数直接量却是函数结构的一个静态部分,就像function语句一样。 

其次,作为第一个差别的必然结果,每次调用构造函数Function()时都会解析函数体并且创建一个新东汉数对象。如果对构造函数的调用出现在一个循环中,或者出现在一个经常被调用的函数中,这种方法的效率非常低。另一个方面,函数直接量或出现在循环和函数中的嵌套函数不是在每次调用时都被重新编译,而且每当遇到一个函数直接量时也不创建一个新的函数对象。 

Function()构造函数和函数之间量之间的第三点差别是,使用构造函数Function()创建的函数不使用词法作用域,相反的,它们总是被当作顶级函数来编译,就像下面代码所说明的那样: