zoukankan      html  css  js  c++  java
  • 研磨JavaScript系列(三):函数的魔力

    JavaScript的代码中就只有function一种形式,function就是函数的类型。在其他的编程语言中可能还存在Procedure或者是method等代码概念,在JavaScript中只有function这一种形式。当我们写下一个函数的时候,只不过是建立了一个function类型的实体而已。

    1 <script type="text/javascript">
    2 function myFunc(){
    3     alert("hello");
    4 }
    5 
    6 alert(typeof(myFunc));    //结果是输出function
    7 </script>

    这个代码运行之后可以看到typeof(myFunc)返回的是function。以上的函数写法我们称之为"定义式"的,将其改写成"变量式"的,就更容易理解了。

    1 <script type="text/javascript">
    2 var myFunc = function(){
    3     alert("hello");
    4 }
    5 
    6 alert(typeof(myFunc));    //结果是输出function
    7 </script>

    这里就明确定义了一个变量myFunc,它的初始值被赋予了一个function的实体,因此,typeof(myFunc)返回的也是function。其实,这两种函数的写法是等价的,除了一点细微差别,其内部实现完全相同。也就是说,我们写的这些JavaScript函数只是一个命了名的变量而已,其变量类型就是function,变量的值是我们编写的函数体。

    函数既然只是变量,那么变量可以被随意赋值并用到任意地方?

     1 <script type="text/javascript">
     2 var myFunc = function(){
     3     alert("hello");
     4 }
     5 
     6 myFunc();     //输出hello
     7 
     8 myFunc = function(){
     9     alert("yeah"); 
    10 }
    11 
    12 myFunc();     //输出yeah
    13 </script>

    是的,没错。这段代码首先定义了一个变量myFunc,并赋值了一个函数给他。当第一次调用myFunc()函数的时候,输出了hello。然后myFunc变量又被赋值了一个新的函数,在第二次调用myFunc()函数的时候,函数的输出发生了变化,输出了yeah。

    好了,我们再看一段代码

     1 <script type="text/javascript">
     2 function myFunc(){
     3     alert("hello");
     4 }
     5 
     6 myFunc();     //输出yeah,这里居然输出的是yeah,而不是hello奇怪吗?
     7 
     8 function myFunc(){
     9     alert("yeah");
    10 }
    11 
    12 myFunc();     //当然是输出yeah
    13 </script>

    这里奇怪的事情发生了,为什么我们第一次调用myFunc的时候也是输出yeah,而不是输出hello呢?还有,按理说,两个签名相同的函数,在编程语言中应该是非法的,这里怎么可以这样? 

    在JavaScript中,这样的写法是没有错误的。不过,在程序运行的时候就出现了一个奇怪的现象,就是,在两次调用函数时输出的值都是一样的,显然是第一个函数没有起到任何的作用。

    原来,JavaScript执行引擎并非是一行一行地分析和执行代码的,而是一段一段地分析执行的。而且,在同一个程序的分析执行中,定义式的函数语句会被提取出来优先执行。函数定义执行完之后,才会按顺序执行其他语句代码。也就是说第一次调用myFunc之前,第一个函数语句定义的代码逻辑,已经被第二个函数定义语句覆盖了。所以,两次调用的其实都是执行了最后一个函数逻辑了。

    我们再看看下面的代码,把这个JavaScript代码分成两段,将他们用<script>标签各自包含起来。

     1 <script type="text/javascript">
     2 function myFunc(){
     3     alert("hello");
     4 }
     5 
     6 myFunc();     //输出hello
     7 </script>
     8 <script type="text/javascript">
     9 function myFunc(){
    10     alert("yeah");
    11 }
    12 
    13 myFunc();     //输出yeah
    14 </script>

    这时,才是各自按顺序输出的,也证明了JavaScript的确是一段段地执行代码的。

    一段代码中的定义式函数语句会优先执行,似乎有点像静态语言的编译概念。所以,这一特征也被有些人称为JavaScript的预编译。事实上JavaScript执行引擎的预编译还包括对所有var变量的创建(初始值为undefined),以提高代码的执行效率。

    JavaScript函数的魔力就在于可以动态改变函数的逻辑,其灵活性远比静态语言的函数指针和虚函数来强大的多。灵活施展JavaScript函数的魔力,可以编写出强大而简洁的代码。

    文章声明:本文部分内容参考自《悟透JavaScript》,这是一本学习JavaScript非常好的书。

  • 相关阅读:
    FreeCommander 学习手册
    String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)
    StringBuffer 详解 (String系列之3)
    StringBuilder 详解 (String系列之2)
    java io系列26之 RandomAccessFile
    java io系列25之 PrintWriter (字符打印输出流)
    java io系列24之 BufferedWriter(字符缓冲输出流)
    java io系列23之 BufferedReader(字符缓冲输入流)
    java io系列22之 FileReader和FileWriter
    java io系列21之 InputStreamReader和OutputStreamWriter
  • 原文地址:https://www.cnblogs.com/HLiang/p/magic_of_function.html
Copyright © 2011-2022 走看看