北京网站建设一条龙中山有哪些网站建立公司
web/
2025/9/27 3:17:32/
文章来源:
北京网站建设一条龙,中山有哪些网站建立公司,wordpress官方网站,可以做英文教师的网站数字、布尔值和字符串是构建数据结构的原子。不过#xff0c;许多类型的信息需要不止一个原子。对象允许我们对值#xff08;包括其他对象#xff09;进行分组#xff0c;从而构建更复杂的结构。到目前为止#xff0c;我们所构建的程序都受到限制#xff0c;因为它们只能… 数字、布尔值和字符串是构建数据结构的原子。不过许多类型的信息需要不止一个原子。对象允许我们对值包括其他对象进行分组从而构建更复杂的结构。到目前为止我们所构建的程序都受到限制因为它们只能在简单的数据类型上运行。在本章中学习了数据结构的基础知识后你就可以开始编写有用的程序了。 本章将通过一个或多或少现实的编程示例介绍适用于当前问题的概念。示例代码通常以本书前面介绍的函数和绑定为基础。
松鼠 每隔一段时间通常是晚上 8 点到 10 点之间雅克就会发现自己变成了一只毛茸茸的小啮齿动物尾巴上还长满了毛。一方面雅克很庆幸自己没有典型的变狼症。与变成狼相比变成松鼠带来的问题确实要少一些。他不用担心不小心吃掉邻居那就尴尬了而是担心被邻居家的猫吃掉。有两次雅克在橡树树冠上一根岌岌可危的细树枝上醒来浑身赤裸神志不清后来他就习惯了晚上锁上房间的门窗在地板上放几个核桃让自己忙起来。 但雅克更希望完全摆脱这种状况。变身的不规则发生让他怀疑可能是由什么东西引发的。有一段时间他认为只有在靠近橡树的日子里才会发生这种情况。然而避开橡树并不能解决问题。雅克转而采用一种更科学的方法他开始每天记录自己在某一天所做的每一件事以及自己是否改变了形态。他希望通过这些数据缩小引发变形的条件范围。
他首先需要一个数据结构来存储这些信息。
数据集 要处理一大块数字数据我们首先要找到一种在机器内存中表示它的方法。比如说我们想表示一组数字 2、3、5、7 和 11。我们可以创造性地使用字符串--毕竟字符串可以有任意长度因此我们可以在字符串中放入大量数据--然后使用 “2 3 5 7 11 ”来表示。但这样做很笨拙。我们必须以某种方式提取数字并将其转换为数字才能访问它们。 幸运的是JavaScript 提供了一种专门用于存储数值序列的数据类型。这种数据类型被称为数组其写法是在方括号之间用逗号分隔的值列表。 查找数组内部元素的符号也使用方括号。在一个表达式后面紧跟一对方括号方括号内还有另一个表达式这样就可以查找左侧表达式中与括号内表达式给出的索引相对应的元素。 数组的第一个索引是 0而不是 1因此第一个元素用 listOfNumbers[0] 来检索。基于零的计数法在技术领域有着悠久的传统在某些方面非常合理但需要一些时间来适应。将索引视为要跳过的项数从数组的起点开始计数。
属性 我们在过去的章节中见过一些表达式如 myString.length获取字符串长度和 Math.max最大值函数。这些表达式访问某个值的属性。在第一种情况下我们访问 myString 中值的length属性。在第二种情况中我们访问的是 Math 对象它是数学常量和函数的集合中名为 max 的属性。 几乎所有 JavaScript 值都有属性。null 和undefined是例外。如果尝试访问这些非值的属性就会出现错误 JavaScript 中访问属性的两种主要方式是使用点和方括号。value.x 和 value[x] 都可以访问 value 上的一个属性但不一定是同一个属性。两者的区别在于如何解释 x。
使用点时点后面的单词是属性的字面名称。使用方括号时括号之间的表达式将被求值以获得属性名称。 value.x 获取名为 “x ”的值的属性而 value[x] 则获取名为 x 的变量的值并将其转换为字符串作为属性名。 如果你知道你感兴趣的属性叫做 color你就会说 value.color。如果要提取由绑定 i 中的值命名的属性则需要输入 value[i]。属性名是字符串。它们可以是任何字符串但点符号只适用于看起来像有效绑定名称的名称--以字母或下划线开头且只包含字母、数字和下划线。如果要访问名为 2 或 John Doe 的属性必须使用方括号value[2] 或 value[“John Doe”]。 数组中的元素存储为数组的属性使用数字作为属性名。由于数字不能使用圆点符号而且通常要使用保存索引的绑定因此必须使用括号符号来获取它们。
就像字符串一样数组也有一个length属性告诉我们数组有多少个元素。
方法
除了length属性外字符串和数组值都包含一些存放函数值的属性。 每个字符串都有一个 toUpperCase 属性。调用时它会返回一个字符串副本其中所有字母都已转换为大写。还有一个 toLowerCase 属性与之相反。有趣的是虽然调用 toUpperCase 时没有传递任何参数但函数却可以访问字符串 “Doh”也就是我们调用的属性值。我们将在第 6 章中了解其工作原理。
包含函数的属性通常被称为其所属值的方法如 “toUpperCase 是字符串的一个方法”。
本例演示了两种可以用来操作数组的方法。 push 方法将值添加到数组的末尾。pop 方法则相反删除数组中的最后一个值并将其返回。 这些有点愚蠢的名称是对堆栈进行操作的传统术语。在编程中堆栈是一种数据结构先进后出它允许你以相反的顺序将数值推入堆栈并弹出这样最后加入的数值就会被先移除。堆栈在编程中很常见你可能还记得上一章中的函数调用堆栈它也是相同思想的一个实例。
对象 回到松鼠。一组每日日志条目可以表示为一个数组但这些条目并不仅仅由数字或字符串组成--每个条目都需要存储一个活动列表和一个布尔值该布尔值表示 Jacques 是否变成了松鼠。理想情况下我们希望将这些值组合成一个单一值然后将这些组合值放入日志条目的数组中。
对象类型的值是属性的任意集合。创建对象的一种方法是使用大括号作为表达式。 在大括号内你可以写出一个用逗号分隔的属性列表。每个属性都有一个名称后面跟一个冒号和一个值。当一个对象写了多行时按本示例所示缩进有助于提高可读性。名称不是有效绑定名称或有效数字的属性必须加引号 这意味着大括号在 JavaScript 中具有两种含义。在语句的开头它们表示一个语句块的开始。而在其他任何位置它们则描述一个对象。幸运的是用大括号中的对象来开始语句的情况很少因此这两者之间的歧义并不是什么大问题。唯一会出现这种情况的是当你想从一个速记箭头函数中返回一个对象时--你不能写 n {prop: n}因为大括号会被解释为函数体。相反你必须在对象周围加上一组括号以明确它是一个表达式。 读取一个不存在的属性会得到undefined的值。可以使用 操作符为属性表达式赋值。如果该属性已经存在则会替换该属性的值如果不存在则会在对象上创建一个新属性。 简单地回到我们的绑定触手模型--属性绑定与此类似。它们掌握值但其他绑定和属性也可能掌握这些相同的值。你可以把对象想象成拥有任意数量触手的章鱼每个触手上都写着一个名字。 删除操作符切断了章鱼的触角。它是一个一元操作符当应用于对象属性时将从对象中删除指定的属性。这种操作并不常见但却是可能的。 二进制 in 运算符在应用于字符串和对象时会告诉你该对象是否具有该名称的属性。将属性设置为 undefined 与实际删除属性之间的区别在于在第一种情况下对象仍然拥有该属性只是没有非常有趣的值而在第二种情况下属性不再存在in 将返回 false。 要想知道一个对象有哪些属性可以使用 Object.keys 函数。给该函数一个对象它将返回一个字符串数组--对象的属性名称 有一个 Object.assign 函数可以将一个对象的所有属性复制到另一个对象中 因此数组只是一种专门用于存储事物序列的对象。如果对 typeof [] 进行运算就会产生 “对象”。你可以把数组想象成又长又扁的章鱼所有的触角都整齐地排成一行并标上数字。
雅克将用对象数组来表示雅克保存的日记 可变性
我们很快就会开始实际编程但首先还要了解一个理论。 我们看到对象的值是可以修改的。前面几章讨论过的数值类型如数字、字符串和布尔值都是不可改变的--不可能改变这些类型的值。你可以将它们组合起来并从中导出新的值但是当你获取一个特定的字符串值时该值将始终保持不变。其中的文本无法更改。如果您有一个包含 “cat ”的字符串其他代码不可能改变字符串中的某个字符使其拼写成 “rat”。 对象的工作原理则不同。您可以更改对象的属性从而使单个对象的值在不同时间具有不同的内容。 当我们有 120 和 120 这两个数字时无论它们是否指向相同的物理位我们都可以认为它们是相同的数字。对于对象有两个对同一对象的引用与有两个包含相同属性的不同对象是不同的。请看下面的代码 object1 和 object2 绑定掌握的是同一个对象这就是为什么改变 object1 也会改变 object2 的值。可以说它们具有相同的身份。绑定 object3 指向一个不同的对象它最初包含与 object1 相同的属性但过着独立的生活。 绑定即变量的定义方式可以是可变的使用 let或恒定的使用 const但这与绑定的值是否可以改变是不同的。使用 let 定义的变量可以改变其值而 const 定义的对象虽然不能重新绑定但对象的内部属性可以改变。简单来说const 保证了变量不会指向其他对象但对象的内容可以变化。 使用 JavaScript 的 运算符比较对象时它是通过同一性进行比较的只有当两个对象的值完全相同时它才会返回 true。比较不同的对象将返回 false即使它们具有相同的属性。JavaScript 中并没有内置按内容比较对象的 “深层 ”比较操作但可以自己编写这是本章结尾的练习之一。
狼人日志
雅克启动了 JavaScript 解释器并设置了保存日志所需的环境 请注意添加到日志中的对象看起来有点奇怪。它没有声明事件events 这样的属性而只是给出了一个属性名events。这是一种速记意思是一样的--如果在括号符号中的属性名称后面没有值那么它的值就取自同名的绑定。译者events和squirrel会变成对象的属性
每天晚上 10 点--有时是第二天早上雅克从书柜顶层爬下来后记录一天的工作 一旦有了足够的数据点他就打算用统计学的方法找出这些事件中哪些可能与松鼠相关。 相关性是衡量统计变量之间依赖关系的一种方法。统计变量与编程变量不太一样。在统计学中通常会有一组测量值每个变量在每次测量时都会被测量。变量之间的相关性通常用-1 到 1 之间的数值表示。零相关性表示变量之间没有关系。相关性为 1 表示两者完全相关--如果你知道其中一个你也就知道了另一个。负 1 也表示变量之间完全相关但却是对立的--当其中一个为真时另一个就是假的。 要计算两个布尔变量之间的相关性我们可以使用 phi 系数 (ϕ )。这是一个公式其输入是一个频率表其中包含观察到变量不同组合的次数。公式的输出是一个介于 -1 和 1 之间的数字用来描述相关性。
我们可以把 “吃披萨 ”这一事件放在这样一个频率表中每个数字表示在我们的测量中该组合出现的次数。 如果我们将该表称为 n 表就可以用下面的公式计算出 ϕ (如果此时你正放下书本专注于回味 10 年级数学课的可怕情景--请稍等一下我并不想用无穷无尽的神秘符号来折磨你--现在只有一个公式。即使是这个公式我们所要做的也只是将它转化为 JavaScript。 符号 n01 表示第一个变量squirrelness为假0第二个变量pizza为真1的测量次数。在披萨表中n01 是 9。 n1- 指的是第一个变量为真时的所有测量值的总和在示例表中为 5。同样n-0 指的是第二个变量为假的所有测量值的总和。 因此在披萨表中除法线以上的部分红利是 1×76-4×9 40除法线以下的部分除数是 5×85×10×80 的平方根即 √340,000。得出的结果是 ϕ ≈ 0.069这是一个很小的数字。吃披萨似乎对变换没有影响。
计算相关性 在 JavaScript 中我们可以用一个四元素数组[76, 9, 4, 1]来表示一个二乘二的表格。我们还可以使用其他表示方法例如包含两个二元素数组的数组[[76, 9], [4, 1]]或者包含属性名称如 “11 ”和 “01”的对象但平面数组非常简单而且访问表格的表达式也非常简短。我们将数组的索引解释为两位二进制数其中最左边最显著的数字指的是松鼠变量最右边最不显著的数字指的是事件变量。例如二进制数 10 表示雅克确实变成了松鼠但事件比如 “披萨”没有发生。这种情况发生了四次。由于二进制数 10 在十进制中表示为 2我们将把这个数字存储在数组的索引 2 中。
这个函数就是从这样的数组中计算出 ϕ 系数 这是 ϕ 公式在 JavaScript 中的直接转换。Math.sqrt 是平方根函数由标准 JavaScript 环境中的 Math 对象提供。我们必须从表格中添加两个字段才能得到 n1- 这样的字段因为行或列的总和并没有直接存储在我们的数据结构中。 雅克写了三个月的日记。由此产生的数据集可在本章的编码沙盒存储在 JOURNAL 绑定中和可下载文件中找到。 要从日志中提取特定事件的二乘二表我们必须循环查看所有条目并统计该事件与松鼠变换相关的出现次数 数组有一个包含方法用于检查数组中是否存在给定值。函数使用该方法来确定其感兴趣的事件名称是否是给定日期的事件列表的一部分。 tableFor 循环的主体通过检查条目是否包含感兴趣的特定事件以及该事件是否与松鼠事件同时发生来确定每个日志条目属于表中的哪个方框。然后循环会在表中正确的方框中添加一条。 现在我们已经掌握了计算单个相关性所需的工具。剩下的唯一步骤就是为记录的每一类事件找到相关性看看是否有什么特别之处。
循环数组
在 tableFor 函数中有一个这样的循环 这种循环在经典 JavaScript 中很常见每次一个元素地遍历数组是经常出现的情况要做到这一点你需要在数组的长度上运行一个计数器然后依次挑出每个元素。
在现代 JavaScript 中有一种更简单的方法来编写这种循环 当 for 循环在变量定义后使用 of 时它将循环遍历 of 后面给定值的元素。这不仅适用于数组也适用于字符串和其他一些数据结构。我们将在第 6 章讨论其工作原理。
最终分析
我们需要计算数据集中每一类事件的相关性。为此我们首先需要找到每种类型的事件。 通过在事件数组中添加任何未包含在其中的事件名称该函数可以收集所有类型的事件。
使用该函数我们可以看到所有相关性 大多数相关性似乎接近于零。吃胡萝卜、面包或布丁显然不会引发松鼠厌食症。这种转变似乎更多发生在周末。让我们过滤一下结果只显示大于 0.1 或小于-0.1 的相关性 啊哈有两个因素的相关性明显强于其他因素。吃花生对变成松鼠的几率有很强的正向影响而刷牙则有明显的负向影响。
有意思 我们来试试看。 这是一个强有力的结果。这种现象恰恰发生在雅克吃花生又不刷牙的时候。如果他不是一个不注意牙齿卫生的人他甚至永远都不会注意到自己的痛苦。 了解到这一点后雅克完全停止了吃花生并发现自己的变身停止了。但仅仅过了几个月他就发现这种完全像人类的生活方式少了点什么。没有了野外探险雅克几乎感觉不到自己还活着。他决定还是做一只全职的野生动物。他在森林里建起了一座漂亮的小树屋并为它配备了花生酱分配器和长达十年的花生酱供应然后他最后一次改变了自己的形态过上了松鼠短暂而充满活力的生活。
更多数组方法 在结束本章之前我想再向大家介绍一些与对象相关的概念。首先我将介绍一些常用的数组方法。 在本章前面我们介绍了在数组末尾添加和删除元素的 push 和 pop 方法。在数组的起始位置添加和删除元素的相应方法称为 unshift 和 shift。 该程序管理一个任务队列。您可以通过调用 remember(“groceries”) 将任务添加到队列的末尾当您准备好做某事时您可以调用 getTask() 从队列中获取并移除前面的项目。rememberUrgently 函数也会添加任务但会将其添加到队列的前面而不是后面。 要搜索特定值数组提供了 indexOf 方法。该方法从开始到结束搜索数组并返回找到所请求值的索引如果没有找到则返回-1。如果想从末尾而不是起点开始搜索还有一个类似的方法叫做 lastIndexOf indexOf 和 lastIndexOf 都需要一个可选的第二个参数用于指示从哪里开始搜索。 另一个基本的数组方法是 slice它接受开始和结束索引并返回一个只包含这两个索引之间元素的数组。开始索引是包容性的结束索引是排他性的左开右闭。 如果没有给出结束索引slice 将拷贝起始索引后的所有元素。也可以省略起始索引复制整个数组。
concat 方法可用于将数组追加到一起以创建一个新数组类似于 操作符对字符串的作用。 下面的示例展示了 concat 和 slice 的操作。它接收一个数组和一个索引并返回一个新数组该数组是原始数组的副本但删除了给定索引处的元素 如果您传递的 concat 参数不是数组那么该值将被添加到新数组中就像它是一个单元素数组一样。
字符串及其属性 我们可以从字符串值中读取 length 和 toUpperCase 等属性。但如果我们尝试添加一个新属性它却不会粘连。 字符串、数字和布尔类型的值不是对象虽然语言不会抱怨您试图为它们设置新属性但实际上并不存储这些属性。如前所述这些值是不可变的不能更改。 但这些类型确实有内置属性。每个字符串值都有许多方法。其中一些非常有用的方法是 slice 和 indexOf它们类似于同名的数组方法 其中一个区别是字符串的 indexOf 可以搜索包含多个字符的字符串而相应的数组方法只能搜索单个元素 trim方法会删除字符串开头和结尾的空白空格、换行符、制表符和类似字符 上一章中的 zeroPad 函数也是一种方法。该函数名为 padStart参数为所需长度和填充字符 您可以用 split 将一个字符串拆分到另一个字符串的每一次出现上然后再用 join 将其连接起来 使用 repeat 方法可以重复字符串该方法会创建一个新字符串其中包含多个原始字符串的副本并将其粘合在一起 我们已经了解了字符串类型的length属性。访问字符串中的单个字符就像访问数组元素一样我们将在第 5 章讨论一个复杂的问题。 可变参数 函数可以接受任意数量的参数。例如Math.max 计算所有参数的最大值。要编写这样的函数可以在函数的最后一个参数前加上三个点就像这样 调用此类函数时其余参数会绑定到一个包含所有其他参数的数组。如果在 rest 之前还有其他参数它们的值就不在数组中。在 max 中当它是唯一的参数时它将包含所有参数。
您可以使用类似的三点符号来调用一个包含参数数组的函数。 这样就将数组 “分散 ”到函数调用中将其元素作为单独的参数传递。在 max(9, ...numbers, 2) 中可以将数组与其他参数一起包含在内。
方括号数组符号同样允许三点运算符将另一个数组扩散到新数组中 即使在大括号对象中也是如此它会添加另一个对象的所有属性。如果一个属性被多次添加则以最后添加的值为准 数学对象 正如我们所见Math 是一个与数字相关的实用函数包例如 Math.max最大值、Math.min最小值和 Math.sqrt平方根。 Math 对象被用作一个容器用于组合一系列相关功能。只有一个 Math 对象而且它几乎从不作为值使用。相反它提供了一个命名空间这样所有这些函数和数值就不必进行全局绑定。 过多的全局绑定会 “污染 ”命名空间。占用的名称越多就越有可能意外覆盖某些现有绑定的值。例如你可能想在某个程序中将某个函数命名为 max。由于 JavaScript 内置的 max 函数被安全地隐藏在数学对象中因此您不必担心会覆盖它。 许多语言都会在你定义绑定时使用一个已被使用的名称来阻止你或至少警告你。JavaScript 会对使用 let 或 const 声明的绑定进行阻止但相反它不会对标准绑定或使用 var 或 function 声明的绑定进行阻止。 回到数学对象。如果你需要计算三角函数Math 可以帮上忙。它包含 cos余弦、sin正弦和 tan正切以及它们的反函数 acos、asin 和 atan。数字 π圆周率--或至少是适合 JavaScript 数字的最接近的近似值--可作为 Math.PI 使用。有一个古老的编程传统就是用大写字母书写常量值的名称。 如果您不熟悉正弦和余弦不用担心。我将在第 14 章中解释如何使用它们。 上一个示例使用了 Math.random。这是一个每次调用都会返回一个介于 0包含和 1不包含之间的新伪随机数的函数 虽然计算机是确定性机器--如果输入相同的内容它们总是会做出相同的反应--但让它们产生看似随机的数字还是有可能的。为此计算机会保留一些隐藏值每当你要求一个新的随机数时它就会对这个隐藏值进行复杂的计算从而产生一个新值。它存储一个新值并返回从该值派生出来的某个数字。这样它就能以一种看似随机的方式不断产生新的、难以预测的数字。 如果我们想要一个整数而不是小数的随机数可以在 Math.random 的结果上使用 Math.floor四舍五入到最接近的整数 将随机数乘以 10得到一个大于或等于 0 且小于 10 的数字。由于 Math.floor 会向下舍入因此这个表达式会以相同的概率产生 0 到 9 之间的任何数字。 还有函数 Math.ceil表示 “上限”向上舍入到整数、Math.round舍入到最接近的整数和 Math.abs后者取一个数的绝对值即否定负值而保留正值。
解构
让我们回到 phi 函数上来。 这个函数读起来很别扭的一个原因是我们有一个指向数组的绑定但我们更希望有数组元素的绑定--也就是说让 n00 table[0] 等等。幸运的是JavaScript 中有一种简洁的方法可以做到这一点 这也适用于使用 let、var 或 const 创建的绑定。如果知道要绑定的值是一个数组可以使用方括号 “查看 ”该值的内部绑定其内容。
类似的技巧也适用于对象使用大括号代替方括号。 请注意如果尝试对 null 或 undefined 进行重组就会出现错误就像直接尝试访问这些值的属性一样。
可选属性访问 如果不能确定给定值是否产生了一个对象但仍想读取它的一个属性可以使用点符号的变体object?.property. 当 a 不是 null 或 undefined 时表达式 a?.b 的含义与 a.b 相同。当 a 为 null 或 undefined 时它的值为 undefined。在示例中如果您不确定某个属性是否存在或者某个变量可能持有 undefined 的值使用这种表达式会很方便。
在方括号或括号前面加上? JSON 由于属性是对其值的把握而不是将其包含在内因此对象和数组在计算机内存中是以比特序列的形式存储的这些比特序列包含了其内容的地址--在内存中的位置。一个数组的内部包含另一个数组其中至少一个内存区域用于存储内部数组另一个内存区域用于存储外部数组其中除其他外包含一个代表内部数组地址的数字。 如果你想将数据保存在文件中备用或通过网络发送到另一台计算机就必须以某种方式将这些杂乱无章的内存地址转换成可以存储或发送的描述。我想你可以将整个计算机内存连同你感兴趣的值的地址一起发送过去但这似乎不是最好的办法。 我们可以做的是将数据序列化。这意味着将数据转换成平面描述。一种流行的序列化格式叫做 JSON发音为 “Jason”是 JavaScript Object Notation 的缩写。它作为一种数据存储和通信格式在网络上被广泛使用即使是 JavaScript 之外的语言也不例外。 JSON 与 JavaScript 写数组和对象的方式类似但有一些限制。所有属性名都必须用双引号括起来而且只允许使用简单的数据表达式不允许函数调用、绑定或任何涉及实际计算的内容。JSON 中不允许有注释。
日志条目用 JSON 数据表示时可能是这样的 JavaScript 提供了 JSON.stringify 和 JSON.parse 函数用于将数据转换为这种格式。第一个函数接收一个 JavaScript 值并返回一个 JSON 编码字符串。第二个函数接收这样一个字符串并将其转换为它所编码的值 总结 对象和数组提供了将多个值组合成一个值的方法。这样我们就可以把一堆相关的东西放在一个袋子里然后拿着这个袋子到处跑而不用把所有的东西都包起来试图分别抓住它们。 JavaScript 中的大多数值都有属性但 null 和 undefined 值除外。使用 value.prop 或 value[“prop”] 访问属性。对象倾向于使用名称来表示属性并或多或少存储一组固定的属性。而数组通常包含不同数量的概念上相同的值并使用数字从 0 开始作为属性名称。 数组中有一些已命名的属性如length和一些方法。方法是存在于属性中的函数通常作用于作为属性的值。
练习
范围之和
本书的导言中提到了下面这种计算一系列数字之和的好方法 编写一个 range 函数接收两个参数 start 和 end并返回一个数组其中包含从 start 到 end包括 end的所有数字。
代码
function range(start, end) {if (end start) {return [-1];}let result [];for (let i start; i end; i) {result.push(i);}return result;
}
接着编写一个求和函数接收一个数字数组并返回这些数字的和。运行示例程序看看是否确实返回 55。
代码
function sum(arr) {let result 0;for (let i 0; i arr.length; i) {result arr[i];}return result;
}
console.log(sum(range(1, 5)));
作为附加作业修改 range 函数使其包含一个可选的第三个参数该参数表示构建数组时使用的 “步长 ”值。如果没有给定步长元素将以 1 为增量向上移动这与以前的行为一致。函数调用 range(1, 10, 2) 应返回 [1, 3, 5, 7, 9]。确保这也适用于负步长值这样 range(5, 2, -1) 将产生 [5, 4, 3, 2]。
代码
function range(start, end, step 1) {let result [];if (end start) {for (let i start; i end; i i step) {result.push(i);}} else {for (let i start; i end; i i step) {result.push(i);}}return result;
}
反转数组
数组有一个反转方法可以通过颠倒元素出现的顺序来改变数组。在本练习中请编写两个函数 reverseArray 和 reverseArrayInPlace。
第一个函数 reverseArray 将数组作为参数并产生一个新数组该数组中的元素以相反的顺序排列。
第二种是 reverseArrayInPlace它的作用与 reverse 方法相同通过反转数组中的元素来修改作为其参数的数组。两者都不能使用标准的 reverse 方法。
回想上一章中关于副作用和纯函数的说明你认为哪种变体在更多情况下有用哪个运行得更快
代码循环交换
function reverseArray(arr) {let tempArr new Array(arr.length);for (let i 0; i arr.length; i) {tempArr[i] arr[arr.length - 1 - i];}return tempArr;
}
指针控制数组解构
function reverse2(arr) {let left 0;let right arr.length - 1;while (left right) {[arr[left], arr[right]] [arr[right], arr[left]];left;right--;}return arr;
}
console.log(reverse2([1, 2, 3]));
列表
作为通用的值块对象可用于构建各种数据结构。常见的数据结构是列表不要与数组混淆。列表是一组嵌套的对象第一个对象持有第二个对象的引用第二个对象持有第三个对象的引用以此类推 由此产生的对象形成一个链如下图所示 列表的一个好处是它们可以共享部分结构。例如如果我创建两个新值 {value: 0, rest: list} 和 {value: -1, rest: list}其中 list 指的是前面定义的绑定它们都是独立的列表但它们共享构成最后三个元素的结构。原始列表仍然是一个有效的三元素列表。
请编写一个 arrayToList 函数当给定 [1, 2, 3] 作为参数时它可以建立如图所示的列表结构。
代码
function arrayToList(arr) {if (arr.length 0) {return null;}return { value: arr.shift(), rest: arrayToList(arr) };
}
同时编写一个 listToArray 函数从 list 生成一个数组。
代码 添加辅助函数 prepend 和 nth前者接收一个元素和一个列表并创建一个新的列表将该元素添加到输入列表的前面后者接收一个列表和一个数字并返回列表中给定位置的元素0 表示第一个元素如果没有这样的元素则返回未定义的元素。
如果还没有也可以编写 nth 的递归版本。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/82511.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!