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

第一呷 :基础函数

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

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

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

hi,我的新博客地址:ysha.me !!
原文地址:https://www.cnblogs.com/qianlegeqian/p/3632658.html