啊!我想要有一个参数

到现在为止,我们已经了解了没有参数的函数。只说我们的函数没有任何参数,甚至还没说参数是什么。
大多数程序员非常熟悉参数,中学数学就讨论这个了。所以你知道他们是什么,而我也知道你知道他们是什么,但是请耐心对待这个解释!
让我们写一个带参数的函数:

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)的更多相关文章

  1. JavaScript Allongé 第一呷 :基础函数 (1)

    第一呷 :基础函数 关于函数,尽管少,但毫不逊色. 在javascript中,函数是值,但它们不仅仅是简单的数值,字符串,或者甚至复杂的数据结构树或者地图.函数表示要执行的运算.就像数值.字符串和数组 ...

  2. JavaScript Allongé 第一呷 :基础函数 (3) 未完

    闭包与域是时候来看下一个带函数的函数是如何工作的: (function (x) { return function (y) { return x } })(1)(2) //=> 1 首先,我们使 ...

  3. 网站特效离不开脚本,javascript是最常用的脚本语言,我们归纳一下常用的基础函数和语法:

    转载自网络,非原创 1.输出语句:document.write(""); 2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head ...

  4. javascript常用的基础函数或方法——写给新手的我(持续补充)

    1常用基础函数 alert函数:显示一个警告对话框,包括一个OK按钮.这就是传说中的警告框,此框一弹,世界就清静了.举例:   alert("我一旦出现,之前出现的就算了,我屁股后面你们就歇 ...

  5. JavaScript 笔记(1) -- 基础 & 函数 & 循环 & ...

    目录(代码编写): 显示数据 语法 变量 & 变量类型 对象 函数 事件 字符串 运算符 条件语句 循环语句 Break 和 Continue 使用 JS 近两年,现整理下一些基本: HTML ...

  6. 浅谈:javascript的面向对象编程之基础知识的介绍

    在进入javascript的面对对象之前,我们先来介绍一下javascript的几个概念. 1.javascript的面向对象的基本概念 function aa(){ } /* * 这里的aa,在我们 ...

  7. 更优雅的方式: JavaScript 中顺序执行异步函数

    火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...

  8. JavaScript 面向对象开发知识基础总结

    JavaScript 面向对象开发知识基础总结 最近看了两本书,书中有些内容对自己还是很新的,有些内容是之前自己理解不够深的,所以拿出来总结一下,这两本书的名字如下: JavaScript 面向对象精 ...

  9. javascript学习4、Function函数、伪数组arguments

    一.Function函数基础 函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句. 1.函数的作用: 将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动. ...

随机推荐

  1. Sublime Text 相关教程(转)

    曾经有人说过,世界上有两种编辑器,好用和不好用的:而在好用的编辑器中,又分两种,免费的和死贵死贵的.譬如说VIM 和 TextMate,就是免费和死贵的典型.很不幸,今天的主角 Sublime Tex ...

  2. 【应用】图片翻转js

    图片翻转:图片随着鼠标指针划过进行替换 <img src="example.gif" onmouseover="this.src='exampleTwo.gif'& ...

  3. 编码 —— PCM 编码

    PCM:Pulse Code Modulation,脉冲编码调制: 1. 码率的计算 PCM约定俗成了无损编码,因为PCM代表了数字音频中最佳的保真水准,并不意味着PCM就能够确保信号绝对保真,PCM ...

  4. nginx开发_ngx_http_script源码解析

    功能简介 nginx中有很多配置项支持以变量的形式存在,在运行时根据实时值进行处理.例如如下配置: location / { sub_filter '<a href="http://1 ...

  5. npm --- Node.js包管理器

    目录 1. 安装Node.js 2. 运行npm 3. npm介绍 3.1 安装插件 3.2 更新插件 3.3 卸载插件 3.4 查看当前目录中的插件列表 4. 使用cnpm 4.1 安装 npm( ...

  6. SQL Server中查询CPU占用高的SQL语句

    SQL Server中查询CPU占用高的情况,会用到sys.sysprocesses ,dm_exec_sessions ,dm_exec_requests 一.查看当前的数据库用户连接有多少 USE ...

  7. rsync(四)技术报告

    1.1 摘要 本报告介绍了一种将一台机器上的文件更新到和另一台机器上的文件保持一致的算法.我们假定两台机器之间通过低带宽.高延迟的双向链路进行通信.该算法计算出源文件中和目标文件中一致的部分(译者注: ...

  8. Maven安装,配置及更改本地资源库

    安装 1.确保已安装JDK,和配置JAVA_HOME环境变量 . 注:Maven 3.2 要求 JDK 1.6 或以上版本, 而 Maven 3.0/3.1 需要 JDK 1.5 或以上,这里安装的是 ...

  9. 爬虫代码实现六-Queue队列实现循环抓取

    StartDSJCount : package com.dajiangtai.djt_spider.start; import java.util.List;import java.util.Queu ...

  10. jQuery 刷新页面

    window.location.reload();