第一呷 :基础函数

关于函数,尽管少,但毫不逊色。

在javascript中,函数是值,但它们不仅仅是简单的数值,字符串,或者甚至复杂的数据结构树或者地图。函数表示要执行的运算。就像数值、字符串和数组,它们都有一个表现形式。我们从尽可能简单的函数开始。在javascript中,它看起来像这样:

function () {}

这是一个没有使用值也没有产生值的函数。我们如何在javascript中表示“没有值”呢?我们马上就会发现,首先,我们来验证一下函数是一个值:

(function () {})

   //=>[Function]

什么?它为什么没有返回function () {}给我们,这似乎打破了“如果一个表达式是值,它将返回同样的值”这一规则,发生了什么事?最简单且最容易的回答是:尽管javascript解析器确实返回了那个值,呈现到屏幕上却稍微有点不同。[Function]是Node.js的作者做出的选择,javascript环境承载REPL(读取-求值-打印循环:read-eval-print loop) 。如果你在浏览器中测试,你就会看到你键入的代码了。

我更偏爱其他的,但必须承认的是,屏幕反馈给我们的是任意的,并且真正重要的是,它有益于人们阅读。但是我们必须要懂得,不管是看到[Function]还是function () {},在javascript内部有一个完整而适当的函数。

函数和恒等式

你还记得,关于恒等式我们有两种类型的值:值类型和引用类型。如果内容相同,值类型是恒等的,而引用类型不是。

函数是哪一种呢?我们来试一下。由于对javascript解析器让步的原因,我们把函数放在小括号中。

 (function () {}) === (function () {})
//=> false

像数组一样,每次你对一个表达式求值产生一个函数时,你得到的是一个不与任何其他函数相同的新函数,即便你使用同样的表达式来生成它。“Function”是一种引用类型。

应用函数

我们把函数用到现实中来。我们使用函数的方式是把它们运用到零个或多个被称为参数的值。正如 2+2生成一个值(在这个场景中是4),把一个函数运用到零个或多个参数同样会生成一个值。

这里就是在javascript中,我们如何将函数应用于一些值。我们说fn_expr是一个当我们对其求值时会生成一个函数的表达式,我们把参数称为args,这里就是怎么把函数运用到一些参数了:

fn_expr(args)

现在,我们只知道这样一个表达式:function () {},让我们来使用它。为了让解析器高兴,我们把它放在小括号中,就像我们上面做的那样:(function () {})。由于我们没有给它任何参数,因此我们只是简单地在表达式后面写上小括号。所以我们这样写:

(function () {})()
//=> undefined

这个undefined是什么?

undefined

在javascript中,缺少的值被写为undefined,这意味着没有值。它还会再次出现。

undefined是它自己的类型的值,它就像一个值类型:

 undefined
//=> undefined

像数值、布尔和字符串一样,javascript可以打印出值undefined。

 undefined === undefined
//=> true
(function () {})() === (function () {})()
//=> true
(function () {})() === undefined
//=> true

不管你怎么去求undefined的值,你会得到一个相同的返回值。undefined是一个意为"我没有值"的值,但是它还是一个值。

你可能会想javascript中的undefined如同SQL的NULL,不是的。在SQL中,两个“NULL”的东西不等同于相同,因为两个未知的东西不可能是相等的。在javascript中,每一个undefined和每一个其他的undefined都是相同的。

void

我们看到javascript通过键入undefined代表一个未定义的值,并且我们已经用两种方式生成了undefined值。

1.通过对一个没有返回值的函数求值(function () {})()和;

2.通过我们自己写undefined

这里有第三种方式,使用javascript的void操作符,看:

 void 0
//=> undefined
void 1
//=> undefined
void (2 + 2)
//=> undefined

void是一个操作符,它总是把任何值和求值转为undefined,所以,当我们故意想要一个undefined的值时,我们应该使用第一种、第二种还是第三种形式呢?答案是使用void。按照惯例,使用void 0。

第一种形式虽有效却繁琐,第二种形式大部分时候是有效的,但是通过重新分配undefined一个不同的值有可能打破它,这一点我们将会在重新分配与突变中讨论。第三种形式始终保持正常工作,所以这是我们会使用的。

不带函数体和参数的函数

回到我们的函数,我们这样求值:

(function () {})()
//=> undefined

让我们回想一下,我们将函数function () {}应用到无参数的情况(因为()里面没有东西),所以我们怎么知道会产生undefined呢?这很简单:

当我们定义一个函数的时候,我们写单词function,然后放参数(可能是空的)列表,r然后我们给函数一个括在花括号里的函数体{...}。函数体是用分号分隔的javascript语句列表(可能为空)。

类似: {语句1; 语句2; 语句3; … ; 语句n }

我们还未讨论过这些语句。什么是语句?

javascript语句有许多种,第一种我们已经见过。一个表达式是一个javascript语句。尽管它们并不十分实用,以下都是有效的javascript函数,并且应用时它们的计算结果都为undefined。

 (function () { 2 + 2 })

 (function () { 1 + 1; 2 + 2 })

你也可以用换行符分离语句,约定是使用某种形式的一致缩进。

(function () {
1 + 1;
2 + 2
}) (function () {
(function () {
(function () {
(function () {
})
})
});
(function () {
})
})。。。

最后一种是个怪杰,但是既然函数体可以包含语句,语句可以是表达式,而函数是表达式...你明白了吧。

所以我们应用的时候怎么得到一个返回值的函数呢?使用return关键字和任何表达式:

 (function () { return 0 })()
//=> 0 (function () { return 1 })()
//=> 1 (function () { return 'Hello ' + 'World' })()
// 'Hello World'

return关键字创建一个return 语句,立即终止函数应用并且返回表达式的计算结果。

计算结果为函数的函数

如果一个表达式的计算结果是一个函数,很好,一个表达式,并且如果可以有任何表达式在return 语句的右边,我们可以把计算结果为函数的表达式放在一个函数表达式的右边么?

是的:

 function () {
return (function () {})
}

这是一个函数,它被调用时计算结果为一个函数,而这个返回的函数被调用时计算结果为undefined。让我们用一个简单的术语。不要说“当被调用时,计算结果为__”,我们会说“返回__”。不要说“返回undefined”,我们说“没有返回任何东西”。

所以我们有一个函数,它返回一个没有返回任何东西的函数。同样的:

 function () {
return (function () {
return true
})
}

这是一个函数,它返回一个返回1的函数。

(function () {
return (function () {
return true
})
})()()
//=> true

很好,我们一直很聪明,但是到目前为止这一切看起来很抽象,晶体的衍射本身是美丽而有趣的,但你不能因为想要看它的实际应用而责怪我们,比如能够决定一颗百万光年远的星星的距离。所以,在下一章“我想要一个参数”中,我们会看到如何使函数实用。

JavaScript Allongé 第一呷 :基础函数 (1)的更多相关文章

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

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

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

    啊!我想要有一个参数 到现在为止,我们已经了解了没有参数的函数.只说我们的函数没有任何参数,甚至还没说参数是什么.大多数程序员非常熟悉参数,中学数学就讨论这个了.所以你知道他们是什么,而我也知道你知道 ...

  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. codeforces 460C. Present 解题报告

    题目链接:http://codeforces.com/submissions/ywindysai 题目意思:有 n 朵花,每朵花都有一定的高度(第 i 朵花对应 ai),m 天之后要把这些花送给别人. ...

  2. PHP截取中英文混合字符

    <?php //////////////////////////////////////////////////////////////////// // PHP截取中英文及标点符号混合的字符串 ...

  3. poj3181【Dollar Dayz】

    做完这道题,心里五味陈杂,明明是最水的一道题,我却做了最长的时间. 题意是求用1-k的和表示n的方案数. 显然是个计数dp,但我不会.思考半小时未果. 然后找尹鹏哲,他给我讲了个错的dp方程,结果调试 ...

  4. vim的tab缩进及用空格设置

    编辑~/.vimrc文件,分别设置用空格而不是用tab,一个tab多少个空格,自动缩进多少宽度,显示行号. set expandtabset tabstop=4 set shiftwidth=4 se ...

  5. python 基础之第十三天(xineted服务器,forking,多线程)

  6. eclipse 查找controller

    一.打开eclipse: 二.同时按住Ctrl + Shift + R ; 弹出框如下: 在红色输入框内输入controller 名字即可. 查找控制器里面的方法:Ctrl + O

  7. js 父组件向子组件传参

    有一个父组件页面如上,点击新增或者修改都会弹出同一个子组件如下: 父组件传参到子组件有两种方式: 一.直接把对象当成参数传给子组件,(看上去更简单,经测试发现一个问题,因为新增时要置空对象的所有信息, ...

  8. 如何使用 Jmeter 发送 Json 请求

    公司最近有一个项目,需要持续发送大量的 Json 请求到服务器,从而测试服务器可靠性. 我就发送 Json 请求部分发布这个博客. 一般来说, Json 请求的数据都保存到 CSV 文件中,然后使用 ...

  9. Unix高级环境编程

    [07] Unix进程环境==================================1. 进程终止    atexit()函数注册终止处理程序.    exit()或return语句:    ...

  10. windows下的套接字IO模型

    一般情况下,IO操作的行为受两种因素的影响: IO操作对象的类型(阻塞还是非阻塞) 获取IO操作结果的方式(同步还是异步). 同步就是指操作的发起和操作结果的获取由调用者完成. 异步指操作发起由调用方 ...