观察下面两段代码,试写出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作用域内部是贯穿的
} hello('xxx');
msg();// ReferenceError: msg is not defined
//说明函数式声明的msg也只是存在于hello函数内

二:变量式声明

function hello(msg){
 alert(abc); // 此时为undefined
alert(msg); // 此时为形式参数msg的值
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函数,都是不存在的。

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

  1. JavaScript中var和this定义变量的区别

    JavaScript中var和this定义变量的区别 在js中声明变量时可以使用var和this,但使用this的有很大一部分参考书是没有的,经过查阅相关资料总结如下: 用var和this声明变量,存 ...

  2. 解读JavaScript中的Hoisting机制(js变量声明提升机制)

    hoisting机制:javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 知识点一:javascript是没有 ...

  3. java基础58 JavaScript的几种格式和变量的声明方式(网页知识)

    1.JavaScript的几种格式 1.1.JavaScript的特点 1.跨平台性    2.安全性.(javaScript代码不能直接访问电脑硬盘上的信息) 1.2.Java与javaScript ...

  4. JavaScript中的作用域以及this变量

    原文:Scope and this in JavaScript 今天我想简单讨论下关于JavaScript的作用域和this变量."作用域"的概念就是说.我们的代码能够从哪里去訪问 ...

  5. 通过代数,数字,欧几里得平面和分形讨论JavaScript中的函数式编程

    本文是对函数式编程范式的系列文章从而拉开了与以下延续一个. 介绍 在JavaScript中,函数只是对象.因此,可以构造函数,作为参数传递,从函数返回或分配给变量.因此,JavaScript具有一流的 ...

  6. JavaScript中是如何定义私有变量的

    前言 JavaScript并不像别的语言,能使用关键字来声明私有变量. 我了解的JavaScript能用来声明私有变量的方式有两种,一种是使用闭包,一种是使用WeakMap. 闭包 闭包的描述有很多种 ...

  7. javascript中的正則表達式

    对文本数据进行操作是JavaScript中常见的任务.正則表達式通过同意程序猿指定字符串匹配的模式来简化诸如验证表单中输入是否具有正确格式之类的任务. 1.正則表達式标记: 字符 含义 举例 i 大写 ...

  8. JavaScript中的陷阱(关于变量声明,函数)

    查看:http://www.css88.com/archives/5347#more-5347

  9. [置顶] Ruby,Scala和JavaScript中的函数式编程(一)

    函数式编程(英语:Functional programming)或者函数程序设计,又称泛函编程,是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象.函数编程语言最重要的 ...

随机推荐

  1. MSDN文档篇

    很多人网上下载3~10G不等的MSDN文档,发现,下载完成了不会用 很多人每次都得在线下载文档,手上万千PC,都重新下载不是得疯了? so==> 先看几张图 推荐一个工具:https://vsh ...

  2. Angular企业级开发(3)-Angular MVC实现

    1.MVC介绍 Model-View-Controller 在20世纪80年代为程序语言Smalltalk发明的一种软件架构.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并 ...

  3. android通过webview调起支付宝app支付

    webview在加载网页的时候会默认调起手机自带的浏览器加载网页,用户体验不好.但当用户设置浏览器客户端(setWebViewClient)设置这样的监听事件之后,当请求url的时候就不会打开手机自带 ...

  4. iOS开发之ReactiveCocoa下的MVVM(干货分享)

    最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...

  5. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  6. python与c互相调用

    虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中 ...

  7. Spark踩坑记——初试

    [TOC] Spark简介 整体认识 Apache Spark是一个围绕速度.易用性和复杂分析构建的大数据处理框架.最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apach ...

  8. ABAP实现屏幕自己刷新和跳转功能

    ABAP开发工程中,有时候需要让跳转出的屏幕自动实现跳转和刷新的功能,该功能的实现需要在屏幕PBO 里面调用相应的事件执行. 关键代码为: SET TITLEBAR ' 屏幕自动程序'. IF g_c ...

  9. 企业shell面试题:获取51CTO博客列表倒序排序考试题

    #!/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin HTMLFILE=/home/oldboy/ht ...

  10. Zephyr OS 简介

    最新发布的开源 Zephyr Project™(Zephyr 项目)是一款小型且可伸缩的实时操作系统,尤其适用于资源受限的系统,可支持多种架构:该系统高度开源,对于开发人员社区完全开放,开发人员可根据 ...