四、Javascript 对象和数组
最后一章介绍了变量。使用变量,您可以保存信息以备后用。随着应用变得越来越复杂,记住用户设置、URL 或表单内容的能力变得越来越重要。
使用变量会遇到的一个问题是,不管是什么类型,一次只能保存一条信息。如果你给一个变量赋一个新值,原来的值就没了。这可以防止您持有复杂类型的数据。
为了模拟复杂的事物而创造大量的变量也是不合理的。例如,如果有人正在填写表单,那么很难管理表单中每个项目的所有变量。
对象是分组数据的好方法。Javascript 中也使用对象来帮助您在应用中执行操作。
document
对象就是一个很好的例子。它可以让你浏览浏览器中的 HTML 页面。
Math
对象可以帮助执行数学运算,而Date
对象不仅可以让您检索当前日期,还可以帮助计算过去或未来的日期。它还可以帮助您以正确格式输入日期。
本章将讨论什么是 Javascript 对象,对象如何工作,并解释什么是属性和方法以及它们如何工作。
首先,我们来谈谈主机对象和本机对象的区别。然后,您可以开始学习如何用 Javascript 创建自己的对象。
宿主对象或本机对象
这不是一个很长的部分,但是它将阐明宿主对象和本机对象之间的区别。由于 Javascript 是一种可以在多种环境下工作的语言,因此代码本身在不同的环境下可能会有不同的表现。举例来说,浏览器中可能有些东西,如历史或位置,在服务器上是不可用的。还可能有其他环境,如具有独特功能的移动设备。在很大程度上,我将讨论 Javascript 如何在浏览器中工作。
您可能会遇到术语“同构 Javascript”在这种情况下,Javascript 应用能够同时在客户端(浏览器)和服务器上运行。
本机(有时称为内置)对象是 ECMAScript 标准的一部分。ECMAScript 本身不是一种语言,而是一种脚本语言的规范。Javascript 是该规范最流行的实现。其他实现包括 ActionScript。基于这种理解,ECMAScript 规范将定义独立于环境的对象。这些对象包括
宿主对象是代码运行环境的一部分。例如,浏览器中的宿主对象包括
注意
如果您对浏览器中有哪些本地对象感兴趣,请查看位于 https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects
.
的 MDN web 文档
您构建的许多应用将利用这两种类型的对象。您通常需要一种类型的对象来帮助处理另一种对象。
最常用的主机对象之一是document
对象。您可以使用它来检查当前文档中发生了什么。这方面的一个例子是更新旅行日期。使用document
和Date
对象,您可以按需更新浏览器中的信息。
既然您已经对本机对象和内置对象有了很好的理解,那么让我们深入了解如何使用泛型对象的一些细节。
面试问题
宿主对象和本机对象有什么区别?举几个例子。
解释对象
我提到了能够将数据分组在一起。在这里我将开始解释这是什么意思。
在 Javascript 中,几乎所有东西都是对象。一个对象代表一个“东西”使用事物(或名词)的概念类似于你如何描述现实生活中的物体。现实生活中的物体有时可以被描述为具有高度、重量或颜色。
记住这一点,当想要获得一个对象的细节时,这些细节被称为属性。Javascript 有一长串对象的内置属性和方法。让我们从浏览器的document
对象开始进入列表。
文档对象简介
如果您想知道浏览器中当前加载的文档的标题,您可以这样做:
let currentTitle = document.title;
这里,您正在创建一个变量,就像上一章一样,并为它赋予当前文档中标题的值。
为了让这个有意义,让我们从右边开始,然后向后看。在这里,您将带至document
对象。该对象由浏览器(您的宿主环境)提供。
document
对象有一个名为title
的属性。你可以用点符号(在单词之间用一个.,就像在document.title
中一样)来问“你的头衔是什么?”问题。使用点,你分离出你感兴趣的主要事物,然后要求更多的细节。在这种情况下,您需要文档的标题。如果你想保留这些信息以备后用,你需要一个地方来存放它们。
如果您想从浏览器中检索信息,这很好。但是,您可能会发现自己需要更新浏览器中当前的信息。
其语法非常相似:
document.title = "My New Title";
您可以看到代码与您之前的示例非常相似。在这种情况下,您正在设置属性的值,而不是获取值(编程中经常使用术语“getter”和“setter”)。
本地和宿主对象都有能力使用属性和一种叫做方法的东西来处理信息。方法是允许您对特定数据执行某种处理的函数。一个例子是,如果你想在你的 HTML 文档中找到基于 CSS 类的东西。document
对象可以帮你做到这一点:
let myClassElements = document.getElementsByClassName('myCssClass');
与标题示例类似,document
对象将执行一个函数(记住这个词,以后再说),它将查看整个 HTML 文档,并将使用这个类名的每个 HTML 元素发送回来。
这个方法唯一需要的是一个参数(引号中的字符串)。这样,函数就知道要寻找什么了。
Javascript 中的其他对象更加具体。在下一个例子中,我将讨论什么是数组以及如何使用它。
面试问题
方法和属性有什么不同?使用 getters 和 setters 是什么意思?
数组和堆栈
数组是一个更加专门化的对象。它具有一般对象所没有的功能。数组不仅仅擅长保存数据组;它还擅长将数据保持有序。
形象化阵列工作方式的一种方法是想象一堆盘子。堆栈中的每个板代表数据。当讨论数组中每个元素的位置时,使用的术语是元素。如果你想象从下到上数盘子,通常你会从一开始数,这是有意义的。有些编程语言从 1 开始计数;但是,Javascript 从零开始计数:
let myArray = new Array();
myArray.push('some data'); //count starts at zero
myArray.push('some other data') //count is now one
console.log(myArray[0]) // some data
这是一个向数组添加数据的例子。每向堆叠中添加一个板,堆叠中的板数量就增加一个。Javascript arrays 称之为length
。
我把数组描述成一堆盘子。栈也是一种数据结构。关于数据结构的问题也可能成为你在面试中遇到的问题。
下一个示例显示了如何创建数组并开始添加值:
//create an array using the new operator
let myArray = new Array();
//create an array using square braces
let myOtherArray = [];
这里你有不同的方法来得到相同的结果。每一个都将属于一个数组的相同的属性和方法赋给你的变量。这将把你的变量变成一个数组对象。
既然已经有了 array 对象,就可以使用它附带的属性和方法了。此示例显示了如何添加数据(将样品板添加到堆叠中):
let nameArray = new Array();
nameArray[0] = 'Hunter';
nameArray[1] = 'Hayes';
nameArray[2] = 'Grant';
之前,我说过要数你的盘子。在这个例子中,您为每个新创建的元素分配一个索引值;最终结果是你的数组或堆栈。
这是确保为特定元素赋值的好方法。您可能遇到的一个问题是无序添加元素的能力。这里有一个例子:
let nameArray = new Array();
nameArray[0] = 'Hunter';
nameArray[2] = 'Grant';
虽然这段代码是正确的,而且浏览器不会告诉你它有什么问题,但是如果你试图获取一个还没有赋值的元素,浏览器会返回undefined
。
获取数组的长度
其他语言要求在创建数组时在数组中设置许多元素。Javascript 不会这样做。您可以添加任意多的元素。
在将元素添加到数组中之后,如果您想要获得当前正在处理的元素的总数,您需要使用length
:
var numberOfElements = myArray.length;
在前面的示例中,在向数组中添加数据之前,您通过编号显式地调出了每个元素。如果你只是想给下一个打开的槽添加一些东西,数组对象有一个名为push
的方法。这也是确保元素的编号顺序没有间隔的好方法。
let nameArray = [];
nameArray.push("Norah");
nameArray.push("Emily");
let numOfNames = nameArray.length; //return 2
在这个例子中,使用push
方法向数组中添加两个名字,然后询问数组的长度。如果您想单独访问每个元素,您可以通过元素编号来查询每个元素:
console.log(nameArray[0]); //returns Norah
console.log(nameArray[1]); //returns Emily
你询问关于你的两个元素的信息。记住 Javascript 对条目排序的方式,你需要索引 0 和 1,而不是索引 1 和 2。
您可以为数组的值分配字符串,但是需要注意的是,数组可以保存您喜欢的任何类型的数据。数组的目的是保存数据组。
既然可以向数组中添加信息,那么数组对象中内置了许多有用的工具供您使用。让我们先过一遍循环。
使用循环和过滤器
现在您的数组中已经有了信息,您会经常发现需要在数组中查找特定值的情况。您可能会寻找一个电子邮件地址,甚至是一个空值。遍历所有这些信息的一种方法是使用循环。由于这是经常发生的事情,Javascript 在 array 对象中内置了一些特性来允许您这样做。
let myArray = ['one', 'two', 'three', 'four'];
myArray.forEach((value, index, array) => {
console.log(value); //current value
console.log(index); //current index
console.log(array); //entire array
});
您了解了对象既有属性又有方法。属性帮助描述关于对象的事情,方法是对象用来处理数据的函数。
数组对象有一个名为forEach
的方法。它让您迭代或遍历数组中的每个元素。
查看每个项目的方式是使用函数。我将在下一章详细讨论函数。目前,函数是让环境为您工作的一种方式。当你想要某种动作发生时,你创建一个函数并告诉环境你需要它做什么。
在这个例子中,您有一个forEach
方法。在这个方法中,您添加了一个函数。这个函数由一组括号、一个箭头和一些花括号组成。
箭头函数实际上是一个等号,旁边有一个大于号:=>
。
括号包含定义函数可用数据的值。这里的值是占位符,您可以随意称呼它们。为了说明这一点,我将这些参数称为value
、index
和array
( value
是正在循环的元素的当前值,index
是当前索引号,array
是整个数组)。
这个例子显示了一个名为console.log
的命令。这是开发人员经常使用的东西。
使用浏览器开发工具时,您会看到一个称为控制台的部分。在这里你可以输出你正在处理的东西的当前值。
也可以直接在控制台中编写 Javascript。当你点击回车键时,它将被执行并更新当前页面。
使用forEach
方法,您可以遍历整个数组。如果你想过滤掉数组中的一些信息呢?您可以使用filter
方法来这样做。filter
方法将根据你创建的测试结果返回一个新的数组。
为了完成这项工作,我将引入条件句的概念。条件句问“这是真的吗?”
当您遍历数组并对每个值使用您的条件时,结果将是一个新数组:
let numberArray = [1,2,3,4,5,6,7,8,9];
let oddNumbers = numberArray.filter((value, index, array) => {
if(value % 2){
console.log(value);
return value;
}
});
为了更好地理解它,我们来分解一下。该数组只是一组从 1 到 9 的数字。下一行是保存filter
方法结果的变量。这和你之前做的差不多。方法filter
内部有一个函数。该函数与forEach
方法具有相同的属性。
不同的是,你添加了一个条件:如果当前值不能被 2 整除。如果这是真的,那么取当前值并从中创建一个全新的数组,并将所有其他属于相同参数的元素添加到这个新数组中。
构建到数组中的另外两个方法是map
和reduce
方法。
map
方法让您遍历数组的所有元素,并对每个元素执行某种类型的操作。然后,通过返回函数的结果形成一个新数组,类似于筛选器示例:
let mappedValue = [1,2,3].map( (value, currentValue, currentIndex, array)=> {
return value * 10;
});
console.log(mappedValue) //returns [10,20,30]
使用reduce
方法允许您通过将数组的所有值相加来创建一个值,使用第一个值作为起点,并将所有其他元素的值加到第一个值上:
let reducedValue = [10,1,2,3,4,5,6,7,8,9].reduce( (value, index, array)=> {
return value + currentValue;
});
console.log(reducedValue) //returns 55
面试问题
给定一个数字数组,如何删除所有重复项并只返回唯一值?给定一个数组的长度,哪个数字代表该数组中的最高索引?
摘要
本章讲述了对象的概念。此外,我还谈到了如何存在语言固有的对象(ECMAScript)和环境向您公开的对象(主机对象)。我还说明了对象如何同时具有属性和方法。属性一般被认为是描述数据的方式,而方法是对数据进行操作的方式。我用数组进一步说明了这一点。数组有类似于length
的属性,它描述了数组中有多少元素。
数组也有类似于push
的方法,可以向数组中的下一个可用元素添加新数据。这个对象也有可以处理数组内部数据的方法或函数,使用内置方法为您提供新的数组。
我引入了条件,您可以让您的程序评估您的数据,并根据是否满足某个条件做出选择。我还介绍了箭头函数。
下一章将更详细地介绍常规函数是如何工作的,并将它们与箭头函数进行比较。我还将讨论关键字this
以及上下文的概念。