观察下面两段代码,试写出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. 【Win 10 应用开发】应用预启动

    所谓预启动,其实你一看那名字就知道是啥意思了,这是直接译,也找不到比这个叫法更简练的词了.在系统资源允许的情况下(比如电池电量充足,有足够的内存空间),系统会把用户常用的应用程序在后台启动,但不会显示 ...

  2. SVD奇异值分解的基本原理和运用

    SVD奇异值分解: SVD是一种可靠的正交矩阵分解法.可以把A矩阵分解成U,∑,VT三个矩阵相乘的形式.(Svd(A)=[U*∑*VT],A不必是方阵,U,VT必定是正交阵,S是对角阵<以奇异值 ...

  3. JQuery easyUI DataGrid 创建复杂列表头(译)

    » Create column groups in DataGrid The easyui DataGrid has ability to group columns, as the followin ...

  4. C++随笔:.NET CoreCLR之corleCLR核心探索之coreconsole(1)

    一看这个标题,是不去取名有点绕呢?或者是,还有些问题?报告LZ...你的标题取得有问题,是个病句!↖(^ω^)↗!!!先不要急,其实我今天带给大家的就是CoreCLR中的coreclr.其中它是在名字 ...

  5. 6_Win7下Chrome主页被流氓网站hao123.com劫持后的解决方法。

    今天安装了一个PDF阅读器,免费的,你懂的,结果自己安装的时候没有将默认的选项取消,就被hao123流氓网站劫持啦. 说实话某免费PDF阅读器还算好的,有一个可以供你选择的项.不想某些软件直接就默认选 ...

  6. .net core和angular2之前端篇—1

    2016-10-20更新 今天的这篇文章还是一篇"Hello World",只不过开发环境有所改变--Visual Studio Code+Angular2+Webapck,也算是 ...

  7. Android 解析XML文件和生成XML文件

    解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...

  8. 如何在Open Live Writer(OLW)中使用precode代码高亮Syntax Highlighter

    早先Microsotf的Windows Live Writer(WLW)现在已经开源了,并且更名为Open Live Writer,但是现在Windows Live Writer还是可以现在,Open ...

  9. 【Knockout.js 学习体验之旅】(3)模板绑定

    本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...

  10. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...