API 与 JavaScript 数据结构相关的简要概述。
分享
数据结构就是为工作选择正确的工具。您需要以有序的方式存储数据,还是只需要能够快速存储和检索数据?什么对您的用例更重要:数据结构执行的速度有多快,或者它占用多少内存?不同的数据结构都有优点、缺点和用例,这就是存在不同数据结构的全部原因!
考虑Array
JavaScript 中的 。它是用于存储有序数据的非常好的数据结构,因为您可以通过索引号检索元素。如果你想要数组的第一个元素,你需要做的就是用索引 0: 获取它arrayName[0]
。它还提供各种有用的方法来操作元素,例如.push()
、.pop()
、.sort()
等。但是,如果要查找某个特定元素是否存在于数组中,则可能需要遍历整个数组。
如果我让你记下我给你的一系列数字,然后在最后问我是否给了你一个特定的数字,你可能会在记忆中做到这一点。但如果我要求你在计算机程序中这样做,你就必须选择如何存储数据。让我们看看我们如何构建storeNumber()
和doYouHaveThisNumber()
运行的两种可能性。给定以下数字列表:
1, 250, -42, 0.4, 17
如果我一次给你一个,你会如何存储这些数字?你可能会使用一个数组:
const listOfNumbers = [ ] ;
const storeNumber = num => listOfNumbers 。推(数);
const doYouHaveThisNumber = num => listOfNumbers 。包括(数量);
在此程序中,storeNumber()
向数组添加一个数字,如果该数字存在于数组中则doYouHaveThisNumber()
返回,否则返回。看起来不错,但是如果你有 10000000 个数字呢?可能开始变得很慢,因为遍历整个数组直到找到输入值。truefalsedoYouHaveThisNumber()
Array.prototype.includes()
让我们尝试使用 JavaScript 中的另一种内置数据类型,即Object
. 由于我们想要跟踪的只是我们是否收到了一个特定的数字,我们可以将这些数字存储在一个对象中,并在true
我们收到它们时将它们的值设置为:
const receivedNumbers = { } ;
const storeNumber = num => receivedNumbers [ num ] = true ;
const doYouHaveThisNumber = num => receivedNumbers [ num ] === true ;
在这种情况下,我们在外部会得到相同的结果,但因为从对象中检索值比遍历数组快得多,所以总体结果会更快。
在这两种情况下,代码的公共 API,即我们希望最终用户与之交互的代码部分,保持不变:我们有两个函数,storeNumber()
并且doYouHaveThisNumber()
. 底层实现或功能实际实现的方式发生了变化。
API是应用程序编程接口的首字母缩写词。API 允许最终用户轻松访问数据结构的属性和方法,而无需进行“幕后”工作。
例如,如果你想在数组的末尾添加一个新元素,你不需要遍历整个数组,计算有多少个元素,然后设置等于新值myArray[currentCount + 1]
。相反,您可以只调用.push()
要添加的值。作为一名 JavaScript 程序员,您实际上不需要知道如何将元素添加到数组末尾的实际策略或底层实现.push()
来使用它。
数组的 API提供了许多有用的功能,从在数组的开头和结尾添加和删除元素,到在每个元素上调用函数的迭代器方法。但是,如果您想在数字数组中找到最小的数字,则必须自己实现该功能。
在构建自己的数据结构时,您将实现创建公共 API 的功能。storeNumber()
与和的示例一样doYouHaveThisNumber()
,相同的公共 API 可以用不同的方式实现,因此考虑不同实现的优点和缺点很重要。
API 就像给最终用户的消息。某些语言的类可以具有公共(可以从任何地方调用)或私有(只能从类内调用)的方法或字段。公共方法是该类的最终用户可以调用的方法,而私有方法仅供该类本身使用。JavaScript 并不真正支持这个概念,因此不打算公开的属性通常前面有一个下划线_
。让我们看一个示例,我们想要使用受限 API 构建数据结构。
堆栈是一种数据结构,只允许从堆栈的“顶部”添加(压入)或移除(弹出)数据。碰巧我们可以将数组用作堆栈,因为它已经有一个.push()
and.pop()
方法!但是,数组还允许您将元素添加到开头或通过索引随机访问元素。
我们现在不打算涵盖堆栈数据结构的所有来龙去脉,但为了演示公共 API 与实现,让我们构建一个快速的自定义Stack
类:
类栈{ 构造函数(){ 这个。_array = [ ] ; }}
在 中Stack
,数组本身存储为_array
,因此它向其他开发人员发出了一个信号,即按预期使用Stack
,他们不需要直接访问它。从那里,我们可以实现.push()
和.pop()
方法:
类栈{ 构造函数(){ 这个。_array = [ ] ; }
推(新值){ 这个。_数组。推送(新值); }
弹出(){ 返回这个。_数组。弹出( ) ; }}
现在我们已经创建了一个Stack
数据结构,将与底层数据的直接交互限制为.push()
和.pop()
。开发人员仍然可以访问我们的底层数组来进行其他操作:
const stack = new Stack ( ) ; 堆叠。_数组。unshift ( '值' ) ;
但是他们会破坏班级的预期行为Stack
。公共 API 的全部意义在于我们为其他最终用户提供功能。如果有人在程序中使用我们的Stack
类,我们可以完全改变底层实现,只要最终用户 API 保持不变,他们的程序就应该继续运行。
当您构建自己的类和数据结构时,请务必牢记实现(它在内部需要什么来完成它的工作)和外部 API(它的用户实际上应该如何与之交互?)之间的区别。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。