研磨JavaScript系列(三):函数的魔力
JavaScript的代码中就只有function一种形式,function就是函数的类型。在其他的编程语言中可能还存在Procedure或者是method等代码概念,在JavaScript中只有function这一种形式。当我们写下一个函数的时候,只不过是建立了一个function类型的实体而已。
<script type="text/javascript">
function myFunc(){
alert("hello");
} alert(typeof(myFunc)); //结果是输出function
</script>
这个代码运行之后可以看到typeof(myFunc)返回的是function。以上的函数写法我们称之为"定义式"的,将其改写成"变量式"的,就更容易理解了。
<script type="text/javascript">
var myFunc = function(){
alert("hello");
} alert(typeof(myFunc)); //结果是输出function
</script>
这里就明确定义了一个变量myFunc,它的初始值被赋予了一个function的实体,因此,typeof(myFunc)返回的也是function。其实,这两种函数的写法是等价的,除了一点细微差别,其内部实现完全相同。也就是说,我们写的这些JavaScript函数只是一个命了名的变量而已,其变量类型就是function,变量的值是我们编写的函数体。
函数既然只是变量,那么变量可以被随意赋值并用到任意地方?
<script type="text/javascript">
var myFunc = function(){
alert("hello");
} myFunc(); //输出hello myFunc = function(){
alert("yeah");
} myFunc(); //输出yeah
</script>
是的,没错。这段代码首先定义了一个变量myFunc,并赋值了一个函数给他。当第一次调用myFunc()函数的时候,输出了hello。然后myFunc变量又被赋值了一个新的函数,在第二次调用myFunc()函数的时候,函数的输出发生了变化,输出了yeah。
好了,我们再看一段代码
<script type="text/javascript">
function myFunc(){
alert("hello");
} myFunc(); //输出yeah,这里居然输出的是yeah,而不是hello奇怪吗? function myFunc(){
alert("yeah");
} myFunc(); //当然是输出yeah
</script>
这里奇怪的事情发生了,为什么我们第一次调用myFunc的时候也是输出yeah,而不是输出hello呢?还有,按理说,两个签名相同的函数,在编程语言中应该是非法的,这里怎么可以这样?
在JavaScript中,这样的写法是没有错误的。不过,在程序运行的时候就出现了一个奇怪的现象,就是,在两次调用函数时输出的值都是一样的,显然是第一个函数没有起到任何的作用。
原来,JavaScript执行引擎并非是一行一行地分析和执行代码的,而是一段一段地分析执行的。而且,在同一个程序的分析执行中,定义式的函数语句会被提取出来优先执行。函数定义执行完之后,才会按顺序执行其他语句代码。也就是说第一次调用myFunc之前,第一个函数语句定义的代码逻辑,已经被第二个函数定义语句覆盖了。所以,两次调用的其实都是执行了最后一个函数逻辑了。
我们再看看下面的代码,把这个JavaScript代码分成两段,将他们用<script>标签各自包含起来。
<script type="text/javascript">
function myFunc(){
alert("hello");
} myFunc(); //输出hello
</script>
<script type="text/javascript">
function myFunc(){
alert("yeah");
} myFunc(); //输出yeah
</script>
这时,才是各自按顺序输出的,也证明了JavaScript的确是一段段地执行代码的。
一段代码中的定义式函数语句会优先执行,似乎有点像静态语言的编译概念。所以,这一特征也被有些人称为JavaScript的预编译。事实上JavaScript执行引擎的预编译还包括对所有var变量的创建(初始值为undefined),以提高代码的执行效率。
JavaScript函数的魔力就在于可以动态改变函数的逻辑,其灵活性远比静态语言的函数指针和虚函数来强大的多。灵活施展JavaScript函数的魔力,可以编写出强大而简洁的代码。
文章声明:本文部分内容参考自《悟透JavaScript》,这是一本学习JavaScript非常好的书。
研磨JavaScript系列(三):函数的魔力的更多相关文章
- 研磨JavaScript系列
JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言.同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作.它最初由网景公司 ...
- 研磨JavaScript系列(一):回归简单
想要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原.编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系.JavaScript就是把数据和代码都简化到最原始 ...
- Javascript入门(三)函数
Javascript函数 一.函数定义与执行 <script type="text/javascript"> //define function fun1(){ ale ...
- javascript系列-class4.函数
欢迎加入前端交流群来py: 转载请标明出处! 在火影的世界中存在忍术,忍术是把强大的能量集中在一起以各种各样不同的形式发射出来.怎样使用各种各样的忍术那?通过结印. ...
- Swift系列三 - 函数
函数在任何语言中都是存在的,Swift中函数更加灵活. 一.函数的定义 1.1. 有返回值(形参默认是let,也只能是let) func pi() -> Double { return 3.14 ...
- 研磨JavaScript系列(五):奇妙的对象
在JavaScript中,只有object和function两种东西有对象化的能力.我们先来说说函数的对象化能力. 任何一个函数都可以为其动态地添加或去除属性,这些属性可以是简单类型,可以是对象,也可 ...
- 研磨JavaScript系列(四):代码的时空
对于过程式编程来说,代码执行的时间与数据标识的空间是密不可分的.我们只有把指令执行的具体时刻与标识映射的具体地址结合起来,才能确定程序在执行瞬间的上下文状态.于是,代码时刻与数据标识的结构,就形成了作 ...
- 研磨JavaScript系列(二):没有类
object就是对象的类型.在JavaScript中不管多么复杂的数据和代码.都可以组织成object形式的对象. 但JavaScript没有"类"概念. 看下面这段JavaScr ...
- JavaScript系列:函数 自执行 表达式 声明 定义
可用方式 (function($) {})(jQuery); !function( $ ){}(jQuery); +function( $ ){}(jQuery); -function( $ ){}( ...
随机推荐
- linux下git+github个人使用记录
Linux: 安装git的命令: sudo apt install git 查看版本确认安装成功: git --version 生成密钥: ssh-keygen -t rsa -C "you ...
- hdu 3804树链剖分+离线操作
/* 树链刨分+离线操作 题意:给你一棵树,和询问x,y 从节点x--节点1的小于等于y的最大值. 解:先建一个空树,将树的边权值从小到大排序,将询问y按从小到大排序 对于每次询问y将小于等于y的边权 ...
- poj 1379 模拟退火法
/* 模拟退火法: 找到一些随机点,从这些点出发,随机的方向坐标向外搜索: 最后找到这些随机点的最大值: 坑://if(xx>-eps&&xx<x+eps&& ...
- 51 nod 1079 中国剩余定理
1079 中国剩余定理 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % ...
- codevs——1436 孪生素数 2
1436 孪生素数 2 时间限制: 2 s 空间限制: 1000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 如m=100,n=6 则将输出100 ...
- Ubuntu 16.04开机自动开启数字键盘NumLock
注意:以下方法不适合在登录时开启,只能是登录后开启.而且我经过测试之后会自动暗下去,但是不影响功能使用.这个是BUG的修复方法:https://askubuntu.com/questions/5090 ...
- 21、Java并发性和多线程-Java中的锁
以下内容转自http://ifeve.com/locks/: 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的 ...
- 链表中倒数第N个元素——剑指Offer
https://www.nowcoder.net/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage= ...
- java编程思想——java IO系统
一.什么是IO io在本质上是单个字节的移动.而流能够说是字节移动的载体和方式,它不停的向目标处移动数据.我们要做的就是依据流的方向从流中读取数据或者向流中写入数据. 二.java中支持IO操作的库类 ...
- HDU 4249 A Famous Equation(数位DP)
题目链接:点击打开链接 思路:用d[i][a][b][c][is]表示当前到了第i位, 三个数的i位各自是a,b,c, 是否有进位 , 的方法数. 细节參见代码: #include<cstdio ...