JavaScript Allongé 第一呷 :基础函数 (2)
啊!我想要有一个参数
到现在为止,我们已经了解了没有参数的函数。只说我们的函数没有任何参数,甚至还没说参数是什么。
大多数程序员非常熟悉参数,中学数学就讨论这个了。所以你知道他们是什么,而我也知道你知道他们是什么,但是请耐心对待这个解释!
让我们写一个带参数的函数:
function (room) {}
这个函数有一个参数room,没有函数体。这里是一个带有两个参数但没有函数体的函数:
function (room, board) {}
我很确定,你非常适应这个函数有两个参数的想法,room和board。参数用来做什么呢?当然是用在函数体中。你觉得这是什么?
function (diameter) { return diameter * 3.14159265 }
这是一个给出直径来计算圆周长的函数。我这样解读"当被应用到一个表示直径的值,此函数返回直径乘以3.14159265"。
记得使用一个无参数的函数时,我们写 (function () {})()。使用带参数的函数时,我们把参数放在小括号中,像这样:
(function (diameter) { return diameter * 3.14159265 })(2)
//=> 6.2831853
你也不会对看到如何编写和使用带两个参数的函数而感到惊讶:
(function (room, board) { return room + board })(800, 150)
//=> 950
函数与函数体快速总结
从例子看,在函数体的表达式中如何使用参数对你而言大概是非常明显的,尤其是如果你已经使用过任何编程语言(除了BASIC方言,我记得是在中学,当你调用程序时不允许参数)。
表达式由任意的值(比如 3.14159265, true, 和 undefined),连接表达式的操作符(比如 3 + 2),一些特殊的形式如[1,2,3]用于从表达式中创建数组,或者function (参数) {体语句}用于创建函数组成。
可能其中一个重要的语句是return 语句。return 语句接收任何有效的javascript表达式。
这种松散的定义是递归的,所以我们可以直觉地这样理解(或者使用其他语言的表达式),既然函数可以包含带表达式的返回语句,我们可以写返回函数的函数,或者包含另一个数组表达式的数组,或者返回数组的函数,函数数组,返回函数数组的函数,等等。
function () {
return function () {}
} function () {
return [ 1, 2, 3]
} [1, [2, 3], 4] function () {
return [
(function () { return 1}),
(function () { return 2}),
(function () { return 3})
]
}
按值调用
就像大多数的现代编程语言一样,javascript使用“按值调用”求值策略。这意味着当你写了一些代码将函数应用到表达式时,javascript对所有这些表达式求值并将所得到的值应用于函数。
所以当你写:
(function (diameter) { return diameter * 3.14159265 })(1 + 1)
//=> 6.2831853
内部发生的是,表达式 1 + 1 首先被计算,产生2,然后我们的周长函数被应用于2。
变量和绑定
现在,一切看起来简单明了,我们可以继续前进更详细地讨论参数。我们打算从function (diameter) { return diameter * 3.14159265 }努力深入到像这样的函数:
function (x) { return (function (y) { return x }) }
function (x) { return (function (y) { return x }) }只是看起来疯狂而已,就像我们正在学习英文作为第二语言,而老师向我们保证我们很快就能使用类似antidisestablishmentarianism这样的单词,除了希望使用长单词听起来让人印象深刻以外,这看起来不再有吸引力,直到我们发现自己想要讨论在19世纪英国政治中英国教会中的角色。
但是这里有另外一个学习antidisestablishmentarianism这个单词的理由:我们也许会学习前缀和后缀在英文语法中如何工作。这和function (x) { return (function (y) { return x }) }是一样的,它本身具有一定的重要意义,它也是一个学习造函数的函数,环境,变量,等等的优秀借口。
为了讨论它是如何工作的,我们需要同意几个术语(你可能已经知道它们了,但我们还是一起检测一下然后“同步我们的词典”)。第一个x,是在function (x) ...中的x,它是一个参数,在function (y) ...中的y是另一个参数,第二个x,是在{ return x }中的x,它不是一个参数,它是一个指向值的表达式。参数和变量以同种方式工作,不管我们是在讨论 function (x) { return (function (y) { return x }) }还是仅仅讨论简单的function (x) { return x }。
每次,一个函数被调用(调用意味着被应用到零个或更多参数),一个新环境就被创建了。一个环境是一个(可能是空的)字典,根据名称将变量映射到值,在表达式中的x我们称之为一个变量,它自身是一个表达式,通过查找环境中的值来被计算。
值是怎样被放到环境中的呢?对参数而言,这很简单。当你将函数应用到参数时,就为字典中的每一个参数放了一个入口,所以当我们写:
(function (x) { return x })(2)
//=> 2
发生了这些事:
1 javascript将这个整体解析为一个由几个子表达式组成的表达式。
2 之后它开始对表达式求值,包括对子表达式求值。
3 一个子表达式,function (x) { return x },计算结果为一个函数。
4 另一个2,计算结果为数值2。
5 javascript现在计算将函数应用到参数2。下面就是它有趣的地方...
6 创建一个环境
7 值2在环境中被名称x所绑定。
8 表达式x(函数的右侧)在我们刚刚创建的环境中被计算。
9 我们在环境中计算的变量的值是在该环境中绑定给变量的名字的值,也就是2。
10 这就是我们的结果
当讨论环境时,我们将使用一个不令人吃惊的语法来显示绑定:{x: 2, ...}。意思是,这个环境是一个字典,而值2被绑定给了名称x,并且在字典中或许有其他的我们现在不讨论的东西。
按共享调用
早些时候,我们区分过javascript的值类型与引用类型。在那时,我们看javascript如何区分对象是否是相同的对象,现在是时候再看一下值和引用类型的区别了。
有一个属性javascript一直在维护:当一个值-任何值-被作为参数传递给函数,这个被绑定在函数环境中的值必须与原始的是相同的。
我们说过javascript把值绑定到名称,但未说过把值绑定到名称意味着什么。现在我们可以详细点了:当javascript把一个值类型绑定到名称时,它复制了这个值然后把副本放在环境中。正如你记得的,像字符串和数值的值类型如果有相同的内容它们是彼此相同的,所以javascript可以建很多字符串、数值或者布尔值的副本只要它想。
引用类型呢?javascript不会在任何环境中放引用类型的副本。javascript在环境中放引用类型的引用,当值需要被用到时,javascript根据引用获得原始值。
因为许多引用类型可以共享同样的值,并且因为javascript将引用作为参数传入,javascript可以说是实现了“按共享调用”的语义。按共享调用一般被理解为按值调用的特殊化。并且它解释了为什么一些值被称为值类型而其他值被称为引用类型。
有了这些,我们就准备好看闭包了。当我们将值类型、引用类型、参数和闭包的知识结合在一起的时候,我们就会理解为什么这个函数总是计算结果为true,不管你用了什么参数:
function (value) {
return (function (copy) {
return copy === value
})(value)
}
JavaScript Allongé 第一呷 :基础函数 (2)的更多相关文章
- JavaScript Allongé 第一呷 :基础函数 (1)
第一呷 :基础函数 关于函数,尽管少,但毫不逊色. 在javascript中,函数是值,但它们不仅仅是简单的数值,字符串,或者甚至复杂的数据结构树或者地图.函数表示要执行的运算.就像数值.字符串和数组 ...
- JavaScript Allongé 第一呷 :基础函数 (3) 未完
闭包与域是时候来看下一个带函数的函数是如何工作的: (function (x) { return function (y) { return x } })(1)(2) //=> 1 首先,我们使 ...
- 网站特效离不开脚本,javascript是最常用的脚本语言,我们归纳一下常用的基础函数和语法:
转载自网络,非原创 1.输出语句:document.write(""); 2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head ...
- javascript常用的基础函数或方法——写给新手的我(持续补充)
1常用基础函数 alert函数:显示一个警告对话框,包括一个OK按钮.这就是传说中的警告框,此框一弹,世界就清静了.举例: alert("我一旦出现,之前出现的就算了,我屁股后面你们就歇 ...
- JavaScript 笔记(1) -- 基础 & 函数 & 循环 & ...
目录(代码编写): 显示数据 语法 变量 & 变量类型 对象 函数 事件 字符串 运算符 条件语句 循环语句 Break 和 Continue 使用 JS 近两年,现整理下一些基本: HTML ...
- 浅谈:javascript的面向对象编程之基础知识的介绍
在进入javascript的面对对象之前,我们先来介绍一下javascript的几个概念. 1.javascript的面向对象的基本概念 function aa(){ } /* * 这里的aa,在我们 ...
- 更优雅的方式: JavaScript 中顺序执行异步函数
火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...
- JavaScript 面向对象开发知识基础总结
JavaScript 面向对象开发知识基础总结 最近看了两本书,书中有些内容对自己还是很新的,有些内容是之前自己理解不够深的,所以拿出来总结一下,这两本书的名字如下: JavaScript 面向对象精 ...
- javascript学习4、Function函数、伪数组arguments
一.Function函数基础 函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句. 1.函数的作用: 将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动. ...
随机推荐
- Chrome 插件 Vimium——让你脱离鼠标
下面是帮助,按?就能出现.什么时候忘了可以随时查看.^_^
- Android-Universal-Image-Loader使用介绍
简介 Android上最让人头疼的莫过于从网络获取图片.显示.回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你.Universal Image Loader for Android的目的 ...
- Normalize.css 与传统的 CSS Reset 有哪些区别?
CSS Reset 是革命党,CSS Reset 里最激进那一派提倡不管你小子有用没用,通通给我脱了那身衣服,凭什么你 body 出生就穿一圈 margin,凭什么你姓 h 的比别人吃得胖,凭什么你 ...
- JAVA解析EXCEL(2003和2007)
本文参考: http://wenku.baidu.com/view/707f07d95022aaea998f0fd1.html http://surfingforrest.iteye.com/blog ...
- bzoj4521
数位dp 复习数位dp 数位dp一般用记忆化搜索来解决 观察需要满足的条件,然后计入状态 状态还要记录是否达到上线,以及前导零 比如说这道题 dfs(bit,a4,a8,cnt,last,limit) ...
- Valera and Swaps
题意: 定义 $f(p)$ 表示将 $p$ 序列变换为有序序列最少要交换多少次,给一 $1 \sim n$ 的排列 $a$ ,给一整数 $m$, 求问将 $a$ 最少交换多少次能得到 $p$ ,使得 ...
- Eclipse 安装Maven插件
这个好: http://www.iteye.com/topic/1123225 其他: 1先安装subeclipse插件就是svn svn - http://subclipse.tigris.org/ ...
- eclipse neon 离线安装插件
我的eclipse版本是4.6.3,以安装svn插件为例. 网上查到很多资料都是说找到eclipse目录下"plugins"和"features"文件夹,将下载 ...
- git如何做个人构建
1 基本概念 1.1 Git:Git是一个版本控制的工具,类似于svn. 1.2 Gerrit:Gerrit是一个基于git的团队合作的工具,开发人员可以往上面提交代码, ...
- 解读大内老A的《.NET Core框架本质》
老A说的一句话让我很受启发,想要深入了解框架,你要把精力聚焦在架构设计的层面来思考问题.而透彻了解底层原理,最好的笨办法就是根据原理对框架核心进行重建或者说再造.看起来没有捷径,也是最快的捷径. 题外 ...