javascript中的函数式声明与变量式声明

观察下面两段代码,试写出hello(‘word‘);的运行结果:

// 变量式声明
function hello(msg){
   alert(msg);
   var msg = function(){};
   alert(msg);
}

//函数式声明
function hello(msg){
   alert(msg);
   function msg (){};
   alert(msg);
}

对于变量式声明,首先弹出word,然后弹出function,而函数式声明,则两次都是弹出function.这是为什么呢?

一: 函数式声明

function hello(msg){
   alert(msg); //放在最前面的位置打印msg,是function
   function msg(){
      //这个msg是函数式声明,它会贯穿于整个fun函数的作用域
      //也就是说,只要fun一旦调用,甚至只要是进入语法分析阶段
      //那么msg函数就会首先解析,你可以把它想象成它是在fun函数
      //内的第一个变量。有的书上称这种现象为声明被提前或提升。
   }
   alert(msg);//放在最末尾的位置打印msg,也是function
  // 说明函数式声明在hello作用域内部是贯穿的
}

二:变量式声明

function hello(msg){
 alert(abc); // 此时为undefined

   var abc = function(){
    //这种是变量式声明,它在fun函数内的位置是固定的,也就是说
    // var abc之前,abc的值在fun内是undefined
    // var abc之后,abc才是它声明的值
    // 这种方式你可以理解成在fun函数的第一行写了一个var abc;
    // 也正因为如此,fun内声明的变量,会切断外部变量的引用;
    // 不论在hello作用域之外,abc的值是多少,在hello内部,在var abc之前,始终是undefined
    // 这是面试官最喜欢光顾的地方之一
   }

   alert(abc); // 此时才是function

   // 这里把abc换成msg,道理也是一样的。对于hello内部来说,它的形参,就相当于是hello内部的局部变量。   // 这里有意用abc来替换msg,其实是为了简化问题,减少干扰项。既然是都hello内的局域变量,那么在声明之前   // 它的值为undefined也就是理所当然的事了。这里唯一有个要注意的地方就是,形参的声明,出现在所有局部变量之前。   // 后面对局部变量进行重复声明,系统会直接无视重复的声明过程,但是声明同时有赋值的话除外。
 }

总结一点:函数式声明会上升到所属作用域的最前面, 变量式声明则不会.

最后补充一点:

var abc = function(){};

实际上是abc保存了一个无名函数的引用;本质上abc还是一个变量.

而 function abc(){} 是一个有名函数;本质上abc是函数;

如果你喜欢,你可以用多个变量保存同一个函数的引用:

var xxx = abc; var bbb = abc;

引用可以无数,但是真身始终唯一。

// xxx = null,bbb=null之后,abc该干嘛干嘛,而 var abc = function(){}; abc = null之后你就彻底的失去了有关abc的一切。

abc从此石沉大海,从江湖上隐姓埋名,销声匿迹.......

虽然两者在功能上是等价的,但是呢,我个人还是蛮倾向于把子函数, 人为的写在前面,这是为了避免压缩合并时,造成各种意外的结果。

如果不是通用方法,我习惯用变量式声明,当然,这只是个人习惯。

对于函数式声明,它在整个作用域内可见,有的书上说是声明提升,有的说是声明提前。其实叫什么不重要,理解这种现象发生了什么,会产生什么影响才是根本。

最后还要强调一点:命名函数表达式的名字只在该函数的作用域内部有效。也就是说,在hello函数内,无论用哪种方式声明msg这个函数,那么出了hello函数,都是不存在的。

时间: 2024-10-14 17:53:33

javascript中的函数式声明与变量式声明的相关文章

JS函数式编程【译】4.在Javascript中实现函数式编程的技术

?? Functional Programming in Javascript 主目录上一章 建立函数式编程环境 第四章 在Javascript中实现函数式编程的技术 扶好你的帽子,我们现在要真正进入函数式的思想了. 这章我们继续下面的内容: 把所有的核心概念放到一个集中的范式里 探索函数式编程之美 一步步跟踪函数式模式相互交织的逻辑 我们将贯穿整章建立一个简单的应用做一些很酷的事情 你可能已经注意到,在上一章我们介绍Javascript的函数式库的时候引入了一些概念, 而不是在第二章<函数式编

var声明的变量以及声明的函数

<html> <body> <script> //所有用var声明的变量以及声明的函数 /*var  a = 1; function f(){        alert(a);    var a  = 5; }f();*//*var  a = 1; function f(){        alert(a);     a  = 8;}f();*///上面的代码的处理过程 //    ******全局处理****/*1. 在预处理的阶段:    1.1 读取分析整个源代码

Javascript 中的函数式编程

本文和大家分享的主要是javascript中函数式编程相关内容,一起来看看吧,希望对大家学习javascript有所帮助. 函数式编程(functional programming)或称函数程序设计,又称泛函编程,是一种编程范型,比起命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程. 函数式编程,近年来一直被炒得火热,国内外的开发者好像都在议论和提倡这种编程范式.在众多的函数式语言中,Jav

javascript中的正則表達式

对文本数据进行操作是JavaScript中常见的任务.正則表達式通过同意程序猿指定字符串匹配的模式来简化诸如验证表单中输入是否具有正确格式之类的任务. 1.正則表達式标记: 字符 含义 举例 i 大写和小写不敏感 对于模式/http/i  "http" 和"HttP" 一样能够匹配 g 全局匹配.找出所有匹配字符串,而不不过找到第一个就返回. 经常使用于替换 m 多行匹配 2.正則表達式位置指示符:规定模式在它所匹配的字符串里的位置. 字符 含义 举例 ^ 开头 对

JavaScript中valueOf、toString的隐式调用

今天在群上有人问这样一个问题: 函数add可以实现连续的加法运算函数add语法如下add(num1)(num2)(num3)...;//注意这里是省略号哟,无限使用举例如下:add(10)(10)=20;add(10)(20)(50)=80;add(10)(20)(50)(100)=180;请用js代码实现函数add. 自个琢磨了一会只能Google之,代码如下: function add(num){ var sum=num, tmp=function(v){ sum+=v; return tm

匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型

1. 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被final修饰.2. 原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命周期.局部变量的生命周期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡.而内部类对象生命周期与其它类一样:自创建一个匿名内部类对象,系统为该对象分配内存,直到没有引用变量指向分配给该对象的内存,它才会死亡(被JVM垃圾回收).

Javascript中的循环变量声明,到底应该放在哪儿?

不放走任何一个细节.相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准未来的发展方向匹配?本文将对四种常见的声明循环变量的书写方式进行简单的分析和比较. 习惯1:不声明直接使用 function loop(arr) { for (i = 0; i < arr.length; i++) { // do something } } 非常危险的使用习惯,

【JavaScript】Javascript中的函数声明和函数表达式

Javascript有很多有趣的用法,在Google Code Search里能找到不少,举一个例子: <script> ~function() { alert("hello, world."); }(); </script> 试一下就知道这段代码的意思就是声明一个函数,然后立刻执行,因为Javascript中的变量作用域是基于函数的,所以这样可以避免变量污染,但这里的位运算符『~』乍一看让人摸不到头脑,如果去掉它再运行则会报错:SyntaxError. 在阐述

JavaScript中函数式编程中文翻译

原著由 Dan Mantyla 编写 近几年来,随着 Haskell.Scala.Clojure 等学院派原生支持函数式编程的偏门语言越来越受到关注,同时主流的 Java.JavaScript.Python 甚至 C++都陆续支持函数式编程.特别值得一提的是,在 nodejs 出现后,JavaScript 成为第一种从前端到后台的全栈语言,而且 JavaScript 支持多范式编程.应用函数式编程的最大挑战就是思维模式的改变———从传统面向对象的范式变为函数式编程范式. <JavaScript