整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript中的數據類型,看這一篇就夠了

          JavaScript中的數據類型,看這一篇就夠了

          據類型

          ECMAScript中有5中簡單的數據類型(也成為基本數據類型):Undefined、Null、Boolean、Number、String。還有一種復雜的數據類型——Object

          注:Object本質上是有一組無序的鍵值對組成的

          1 typeof操作符

          鑒于ECMAScript是松散類型的,因此需要一個手段來檢測給定的變量時什么類型,typeof就是負責這個功能的操作符。對一個值使用typeof操作符可能返回下列某個字符串:

          • "undefined"——如果這個值未定義
          • "boolean"——如果這個值是布爾值
          • "string"——如果這個值是字符串
          • "number"——如果這個值是數值
          • "object"——如果這個值是對象或null
          • "function"——如果這個值是函數

          下面舉一些使用typeof操作符的例子:

          var message="some string";
          alert(typeof message);		// "string"
          alert(typeof (message));	// "string"
          alert(typeof 95);			// "number"

          2 Undefined類型

          Undefined類型只有一個值,級特殊的undefined。在使用var聲明變量,但未對其加以初始化時,這個變量就是undefined,例如:

          var message;
          alert(message==undefined);	// true

          也可以將變量直接初始化為undefined:

          var message=undefined;
          alert(message==undefined);	// true

          3 Null類型

          Null類型是第二個只有一個值得數據類型,這個特殊的值是null。從邏輯角度來看,null值表示一個空**對象**指針,這也正是為什么用typeof檢測null值會返回object的原因:

          var car=null;
          alert(typeof car);	//object

          實際上undefined值是派生自null值得,如下例:

          alert(null==undefined);	//true

          但是兩者還是有區別的,如果一個變量暫時不賦值,將來要使用。我們不會把一個變量顯示的定義為undefined,而是會定義為null。

          4 Boolean類型

          Boolean類型是ECMAScript中使用得最多的一種類型,該類型有兩個字面值:true和false。

          var found=true;
          var lost=false;

          雖然Boolean類型的字面值只有兩個,但ECMAScript中所有類型的值都有與這兩個Boolean值等價的值。也就是說能夠定義的所有值要么能轉成true,要么能轉成false,可以用轉型函數Boolean()轉化。

          var message="Hello world";
          var messageAsBoolean=Boolean(message);
          alert(messageAsBoolean);	//true

          下表給出了各種數據類型及其對應的轉換規則:

          注:n/a(或N/A),是not applicable的縮寫,意思是“不適用”。


          在流程控制語句中,會自動執行Boolean轉換,如下所示:

          var message="Hello world!";
          if (message) { 			//這里執行了Boolean轉換,將message轉為true
          	alert("Value is true");
          }

          5 Number類型

          Number類型應該是ECMAScript中最令人關注的數據類型了,直接上例子:

          var intNum=55;		// 十進制的55
          var octalNum=070;		// 八進制的56
          var hexNum=0xA;		// 十六進制的10

          1.浮點數值

          所謂浮點數值,就是該數值中必須包含一個小數點,并且小數點后面必須至少有以為數字,浮點數值的例子:

          var floatNum1=1.1;
          var floatNum2=0.1;
          var floatNum3=.1; 	//有效,但不推薦

          由于浮點數值占用的內存是整數值的兩倍,所以ECMAScript會不失時機地將浮點數值轉換為整數值,如下所示:

          var floatNum1=1.;		//小數后面沒有數字——解析為1
          var floatNum2=10.0;	//整數——解析為10

          還有一種可以表示極大或極小的浮點數值的方法——e表示法,如下所示:

          var floatNum=3.125e7;	

          其含義是3.125*10^7

          var floatNum=3e-7;

          其含義是3*10^(-7)

          2.數值范圍

          由于內存的限制,ECMAScript并不能保存世界上所有的數值。ECMAScript能夠表示的最小數值保存在Number.MIN_VALUE中,這個數值是5e-324;能夠表示的最大數值保存在Number.MAX_VALUE中,這個數值是1.7976931348623157e+308。如果某次計算的結果超過這個范圍,則會被轉換成特殊的Infinity值。

          var result=Number.MAX_VALUE + Number.MAX_VALUE;
          alert(isFinite(result));    //false

          3.NaN

          NaN,即非數值(Not a Number),這個數值用于表示一個本來要返回數值的操作數未返回數值的情況,當計算錯誤的時候,不會拋出錯誤,而是返回一個NaN,這樣就不會影響后面代碼的執行。

          • 任何涉及NaN的操作(例如NaN/10)都會返回NaN
          • NaN與任何值都不相等,包括NaN本身
          alert(NaN==NaN);	//false
          alert(isNaN(NaN));	//true

          4.數值轉換

          有3個函數可以把非數值轉換為數值:Number()、parseInt()、parseFloat()

          • Number()——可以用于任何數值類型
          • parseInt()——用于字符串轉數值
          • parseFloat()——用于字符串轉數值

          Number()函數的轉換規則如下:

          • 如果是Boolean值,true和false將分別被轉換為1和0
          • 如果是數字值,只是簡單的傳入和返回
          • 如果是null值,返回0
          • 如果是undefined,返回NaN
          • 如果是對象,則調用對象的valueOf()方法,然后依照前面的規則轉換返回值
          • 如果是字符串,遵循以下規則:
            • 如果字符串中包含數字,則將其轉換為十進制數值
            • 如果字符串中包含有效的浮點格式,如"1.1",則將其轉換為對應的浮點數值
            • 如果字符串中包含有效的十六進制格式,如"0xf",則將其轉換為相同大小的十進制整數值
            • 如果字符串是空的,則將其轉換為0
            • 如果字符串中包含除上述格式之外的字符,則將其轉換為NaN

          例如:

          var num1=Number("Hello world!");	//NaN
          var num2=Number("");				//0
          var num3=Number("000011");		//11
          var num4=Number(true);			//1

          由于Number()在轉換字符串時比較復雜而且不夠合理,因此更常用的是parseInt()函數。parseInt()會從字符串第一個非空格字符開始掃描,如果第一個字符不是數字符號或者負號,parseInt()就會返回NaN。如果第一個字符是數字字符,parseInt()會繼續解析第二個字符,知道遇到一個非數字字符。例如,"1234blue"會被轉換為1234。"22.5"會被解析成22。

          var num1=parseInt("1234blue");  // 1234
          var num2=parseInt("");          // NaN
          var num3=parseInt("0xA");       // 10(十六進制數)
          var num4=parseInt(22.5);        // 22
          var num5=parseInt("070");       // 56(八進制數)
          var num6=parseInt("70");        // 70(十進制數)
          var num7=parseInt("0xf");       // 15(十六進制數)
          var num8=parseInt("f",16);      // 15(十六進制數,另一種寫法,推薦這么寫)

          parseFloat()與parseInt()類似,但有兩點區別:

          • parseFloat()解析字符串中的第一個小數點是有效的,而第二個小數點無效
          • parseFloat()始終會忽略前導的零
          • 十六進制的字符串始終會被轉換成0
          • 如果字符串可以解析為整數,那么parseFloat()會返回整數
           var num1=parseFloat("1234blue");    // 1234(整數)
           var num2=parseFloat("0xA");         // 0
           var num3=parseFloat("22.5");        // 22.5
           var num4=parseFloat("22.34.5");     // 22.34
           var num5=parseFloat("0908.5");      // 908.5
           var num6=parseFloat("3.125e7");     // 31250000

          6 String類型

          String類型用于表示有零或多個16位Unicode字符組成的字符序列,即字符串。字符串可以用雙引號(")或單引號(')表示,因此下面的寫法都是有效的:

          var firstName="Kobe";
          var lastName='Bryant';

          1.字符字面量

          String數據類型包含一些特殊的字符字面量,也叫轉義序列,用于表示非打印字符,或者具有其他用途的字符。這些字符字面量如下表所示:

          2.字符串的特點

          ECMAScript中的字符串是**不可變**的,也就是說,字符串一旦創建,它們的值就不能改變。要改變某個變量保存的字符,首先要銷毀原來的字符串,然后在用另一個包含新值得字符串填充該變量,例如:

          var lang="Java";
          lang=lang + "Script";

          第二行的動作是,創建一個能容納10個字符的新字符串,然后在這個字符串中填充"Java"和"Script",然后將原來的字符串"Java"和字符串"Script"銷毀。

          3.轉換為字符串

          要把一個值轉換為一個字符串有兩種方式。

          a. toString()方法,該方法返回字符串的一個副本

          var age=11;
          var ageAsString=age.toString();		// 字符串"11"
          var found=true;
          var foundAsString=found.toString();	// 字符串"true"

          由于null和undefined值沒有toString()方法,可以用下面的String()方法轉換為字符串

          b.String()方法,可以將任何類型的值轉換為字符串。

          • 如果值有toString()方法,則電泳該方法并返回相應的結果
          • 如果值是null,則返回"null"
          • 如果值是undefined,則返回"undefined"

          下面看幾個例子:

          var value1=10;
          var value2=true;
          var value3=null;
          var value4;
              
          alert(String(value1));  // "10"
          alert(String(value2));  // "true"
          alert(String(value3));  // "null"
          alert(String(value4));  // "undefined"

          7 Object類型

          ECMAScript中的對象其實就是一組數據和功能的集合。Object對象創建的方法如下:

          var o=new Object();

          Object的每個實例具有如下屬性和方法:

          • constructor:保存著用于創建當前對象的函數。對于前面的例子而言,構造函數就是Object()
          • hasOwnProperty(propertyName):用于檢查給定的屬性在當前對象中是否存在
          • isPrototypeOf(object):用于檢查傳入的對象是否是當前對象的原型
          • propertyIsEnumerablepropertyName():用于檢查給定的屬性能否能用for-in語句來枚舉
          • toLocaleString():返回對象的字符串表示,該字符串與執行環境的地區對應
          • toString():返回對象的字符串表示
          • valueOf():返回對象的字符串、數值或布爾值表示。通常與toString()方法的返回值相同


          如果這篇博客對你有用,點個贊再走唄~

          S中有8種數據類型,分別是:

          1. String(字符串)
          2. Number(數字)
          3. Boolean(布爾值)
          4. Undefined(未定義)
          5. Null(空)
          6. Object(對象)
          7. Symbol(符號)
          8. bigint(在ES2020版本中,定義的一種數據類型),專門用來表示大整數

          數值(Number):

          - 數值就是現實生活中的數字,包括整數(int)和浮點數(float)

          - 在js中,所有的數字都是number類型

          - 數值在計算機底層使用64位的二進制數據保存

          - 所以在JS中,并不是可以精確的表示任意數字

          - 對于整數來說,精確表示最大值 九千萬億,9后邊15個零

          - 特殊的數字:

          Infinity 表示正無窮

          -Infinity 表示負無窮

          NaN (Not a Number) 表示非法數字

          了解:

          - 為了解決JS中不能存儲大整數的問題,在ES2020版本中,

          定義了一種新的數據的數據類型(bigint),專門用來表示大整數

          - 大整數以n結尾,大小沒有限制,但是目前標準還沒有正式推出,

          即使推出也不會立即被所有瀏覽器支持(主要是IE),所以現在只需了解一下即可。

          var a=10; // 整數

          a=3.5; // 浮點數

          // 創建數字時,默認創建的都是10進制的數字,可以通過一些特殊方式,來通過其他的進制來創建數字

          // 0b 開頭表示二進制數字

          // 0o 開頭表示八進制數字

          // 0x 開頭表示十六進制數字

          a=0b10; // 使用二進制的形式創建數字

          a=0o10; // 使用八進制的形式創建數字

          a=0xff; // 使用十六進制的形式創建數字

          //在JS中可以確保大部分整數運算得到一個精確的結果,但是一旦超過16位數字,運算結果是不精確的值

          a=9111111111111432; // 16位整數可以精確表示

          a=91111111111114325; // 超過16位,數字顯示為近似值

          a=911111111111143259111111111111432591; // 當超過一定范圍,數字將會以科學計數法來顯示

          a=911111111111143259111111111111432591 ** 10; // 當數字再大的時候,會顯示Infinity,表示正無窮

          //在JS中,小數可以確保小數點后15位的值準確,超過15位則會顯示近似值

          a=1.123456789012345;

          //在JS中,小數的計算可能會出現近似的結果

          //如果計算要求的精度比較高,千萬不要在JS中直接算

          a=0.1 + 0.2;

          a=10 - 'hello';

          // console.log(a);

          Var b=911111111111143251239111111111111432512391111111111114325123n;

          // console.log(b);


          字符串 (String):

          - 在JS中使用字符串來表示語音、文字這些內容

          - 字符串需要使用引號引起來

          - 單引號雙引號都可以,但是注意不要混合使用

          - 同類型的引號是不能嵌套的

          - 在JS中,使用 \ 作為轉義字符

          例子:

          \" --> "

          \' --> '

          \ --> \

          \t --> 制表符(縮進)

          \n --> 在console換行

          - 引號只在當前行起作用

          var a='Hello';

          a="Hello";

          // a="hello'; //不要這么寫

          // a='Hello Hello "aaaa"';

          a="Hello H\nello \"aa\\aa\"";

          // console.log(a);

          a="hello hello How are you";


          布爾值(boolean):

          布爾值(boolean),主要用來進行邏輯判斷

          - 布爾值只有兩個值:

          true 表示真

          false 表示假

          var a=false;

          console.log(typeof a) // boolean

          - typeof的情況:

          typeof 檢查 數字時,返回 number

          typeof 檢查 字符串時,返回 string

          typeof 檢查 布爾值時, 返回 Boolean


          null和undefined:

          空值(null)

          - 空值就表示沒有,表示空的對象

          - 空值只有一個 null

          未定義(undefined)

          - 當我們聲明了一個變量,又不給變量賦值時,它的值就是undefined

          - 一般我們不會主動為一個變量賦值為undefined

          typeof的返回值:

          檢查 null時,它會返回 object (這個是JS中的bug,一個歷史悠久的bug)

          檢查 undefined時,它會返回 undefined

          var a=null;

          a=undefined; // 通常情況下不會這么寫

          console.log(typeof null);

          console.log(typeof undefined);

          基本數據類型5種:

          在JS中的這幾種數據類型,被統稱為基本數據類型:

          數值(number)

          字符串(string)

          布爾值(boolean)

          空值(null)

          未定義(undefined)

          - 基本數據類型是構建程序的基石,所有的數據都是以上幾種數據組合而成。

          - 所有的基本數據類型,都是不可變的。

          - 在JS中,變量并不真正的存儲值

          - 在JS中,變量就相當于值的別名

          Symbol

          Symbol是一種原始類型,可以使用 Symbol() 來創建一個新的 Symbol 對象。Symbol 通常用于作為對象屬性的鍵(key),因為添加到對象中的 Symbol 屬性不會出現在 for…in 循環、Object.keys()、Object.getOwnPropertyNames() 等方法中。這使得 Symbol 成為一種適合用于定義隱藏的屬性的機制。

          需要注意的是,雖然 Symbol 是基本數據類型之一,但是在邏輯運算中,Symbol 類型的值不能被強制轉換為其他數據類型。

          檢查類型tyepof:

          var a=10;

          var b='10';

          //typeof 用來檢查一個值的類型

          // 注意:typeof檢查的是值的類型,而不是變量的類型(變量也沒有類型)

          //用法:tyepof 值


          console.log(typeof a); //number

          console.log(typeof NaN); //number

          console.log(typeof '10'); // string

          console.log(typeof false); // boolean

          console.log(typeof undefined); //undefined

          console.log(typeof null); // 'object' 是js底層遺留問題


          console.log(typeof Array) // 'function'

          console.log(typeof Function) // 'function'

          console.log(typeof Objcet) // 'function'

          console.log(typeof {}); // 'object'

          console.log(typeof []); // 'object'


          歡迎關注我的原創文章:小伙伴們!我是一名熱衷于前端開發的作者,致力于分享我的知識和經驗,幫助其他學習前端的小伙伴們。在我的文章中,你將會找到大量關于前端開發的精彩內容。

          學習前端技術是現代互聯網時代中非常重要的一項技能。無論你是想成為一名專業的前端工程師,還是僅僅對前端開發感興趣,我的文章將能為你提供寶貴的指導和知識。

          在我的文章中,你將會學到如何使用HTML、CSS和JavaScript創建精美的網頁。我將深入講解每個語言的基礎知識,并提供一些實用技巧和最佳實踐。無論你是初學者還是有一定經驗的開發者,我的文章都能夠滿足你的學習需求。

          此外,我還會分享一些關于前端開發的最新動態和行業趨勢。互聯網技術在不斷發展,新的框架和工具層出不窮。通過我的文章,你將會了解到最新的前端技術趨勢,并了解如何應對這些變化。

          我深知學習前端不易,因此我將盡力以簡潔明了的方式解釋復雜的概念,并提供一些易于理解的實例和案例。我希望我的文章能夠幫助你更快地理解前端開發,并提升你的技能。

          如果你想了解更多關于前端開發的內容,不妨關注我的原創文章。我會不定期更新,為你帶來最新的前端技術和知識。感謝你的關注和支持,我們一起探討交流技術共同進步,期待與你一同探索前端開發的奇妙世界!

          #web網站#

          于 JS 初學者,理解鏈表可能是一項比較困難的任務,因為 JS 沒有提供內置的鏈表。在像 JS 這樣的高級語言中,我們需要從頭開始實現此數據結構,如果你不熟悉此數據結構的工作方式,則實現部分會變得更加困難 ?。

          在本文中,我們將討論如何將鏈表存儲在數據庫中,實現鏈表的添加和刪除,查找以及反轉鏈表等操作。在實現鏈表之前,需要知道相比數組和對象,鏈表的優點是什么。

          我們知道,數組中的元素以索引編號和順序存儲在數據庫中:

          在使用數組時,在開始或特定索引處添加/刪除元素這樣的操作可能是一項性能較低的任務,因為我們必須移動所有其他元素的索引,造成這種原因是由數組的編號索引特性導致的。

          使用對象可以解決上述問題。由于在對象中,元素存儲位置是隨機的,因此,在執行諸如在開始處或特定索引處添加/刪除元素之類的操作時,無需移動元素的索引:

          盡管在對象中添加和刪除元素速度很快,但是從上圖可以看出,在進行迭代操作時,對象并不是最佳選擇,因為對象的元素存儲在隨機位置。因此,迭代操作可能需要很長時間。這是鏈表引出的原因。

          那么什么是鏈表呢 ?

          從名字本身可以看出它是一個以某種方式鏈表。那么它是如何鏈接的,列表包含什么呢?

          鏈表由具有兩個屬性的節點組成:數據和指針

          節點內的指針指向列表中的下一個節點。鏈表中的第一個節點稱為head。為了更好地理解,讓我們看一下描述鏈表圖示:

          從上圖可以看出,每個節點都有兩個屬性,datapointer。指針指向列表中的下一個節點,最后一個節點的指針指向null,上圖是一個單鏈表 ?。

          鏈表和對象時有很大的不同。在鏈表中,每個節點都通過指針(pointer)連接到下一個節點。因此,我們在鏈表的每個節點之間都有連接,而在對象中,鍵值對是隨機存儲的,彼此之間沒有連接。

          本文由小智翻譯,歡迎關注《大遷世界

          接著,我們實現一個存儲整數的鏈表。由于 JS 不提供內置的鏈表支持,因此我們將使用對象和類來實現鏈表 ?

          class Node {
            constructor (value) {
              this.value = value
              this.next = null
            }
          }
          
          class LinkedList {
            constructor () {
              this.head = null
              this.tail = this.head
              this.length = 0
            }
            append (value) {
            }
          
            prepend (value) {
          
            }
          
            insert (value, index) {
          
            }
          
            lookup (index) {
          
            }
          
            remove (index) {
          
            }
          
            reverse () {
              
            }
          }
          

          在上面的代碼中,我們創建了兩個類,一個用于來鏈表本身,一個是節點本身。如我們所討論的,每個節點將具有兩個屬性,一個和一個指針(對應 next 字段)。

          LinkedList類包含三個屬性,head(初始值為null),用于存儲鏈表的最后一個節點的tail(也指向null)和用于保存鏈表長度的length屬性。接著,我們來實現里面的方法 ?。

          append (按順序添加值)

          這個函數將一個節點添加到鏈表的末尾。為了實現這個函數,我們需要理解它需要執行的一些操作:

          從上圖中,我們可以通過以下方式實現append函數:

            append (value) {
              const newNode = new Node(value)
              if (!this.head) {
                this.head = newNode
                this.tail = newNode
              } else {
                this.tail.next = newNode
                this.tail = newNode
              }
              this.length++
            }
          

          簡單的對 append 方法解釋一下 ?:

          const linkedList1 = new LinkedList()
          linkedList1.append(2)
          

          檢查head是否指向null,此時的head指向null,因此我們創建一個新對象,并將新對象分配給headtail:

          let node = new Node(2)
          this.head = newNode
          this.tail = newNode
          

          現在,headtail 都指向同一個對象,這一點很重要,要記住。

          接著,我們再向鏈表添加兩個值:

          linkedList1.append(3)
          linkedList1.append(4)
          

          現在,head 不指向null,所以我們進入append函數的else分支:

          this.tail.next = node
          

          由于headtail 都指向同一個對象,tail的變化都會導致head對象的變化,這是JS 中對象的工作方式。在JavaScript中,對象是通過引用傳遞的,因此 headtail都指向存儲對象的相同地址空間。上面這行代碼相當于

          this.head.next = node;
          

          下一行:

          this.tail = node
          

          現在,在執行完上面的代碼行之后,this.head.nextthis.tail指向同一對象,因此,每當我們添加新節點時,head對象都會自動更新。

          執行三次append之后,linkedList1 的結構應該是這樣的:

          head: {value: 2 , next: {value: 3, next: {value: 4,next: null}}}
          tail : {value: 4, next: null}
          length:3
          

          從上面的代碼中我們可以看到,鏈表的append函數的復雜度是O(1),因為我們既不需要移動索引,也不需要遍歷鏈表。

          我們來看下一個函數 ?

          prepend (將值添加到鏈表的開頭)

          為了實現此函數,我們使用Node類創建一個新節點,并將該新節點的下一個對象指向鏈表的head 。接下來,我們將新節點分配給鏈表的head

          與append函數一樣,這個函數的復雜度也是O(1)。

            prepend (value) {
            const node = new Node(value)
          
            node.next = this.head
            this.head = node
            this.length++
          }
          

          就像append函數一樣,此函數的復雜度也為O(1)

          insert (在特定索引處添加值)

          在實現此函數之前,我們先看看它的一個轉化過程。因此,出于理解目的,我們先創建一個值很少的鏈表,然后可視化insert函數。insert 函數接受兩個參數,值和索引:

          let linkedList2 = new LinkedList()
          linkedList2.append(23)
          linkedList2.append(89)
          linkedList2.append(12)
          linkedList2.append(3)
          
          linkedList2.insert(45,2)
          

          第1步:

          遍歷鏈表,直到到達index-1位置:

          第2步:

          將索引為1的節點的指針(在本例中為89)分配給新節點(在本例中為45):

          第3步:

          將新節點(45)的 next 指向給下一個節點(12)

          這就是執行插入操作的方式。通過以上可視化,我們觀察到需要在index-1位置和index位置找到節點,以便可以在它們之間插入新節點。在代碼中實現:

          insert (value, index) {
            if (index >= this.length) {
            this.append(value)
          }
          
            const node = new Node(value)
          
            const { prevNode, nextNode } = thisg.getPrevNextNodes(index)
            prevNode.next = node
            node.next = nextNode
          
            this.length++
          }
          

          簡單分析一下上面的函數:

          如果index的值大于或等于length屬性,則將操作移交給append函數。對于 else 分支,我們使用 Node 類創建一個新節點,接下來觀察一個新函數getPrevNextNodes(),通過該函數我們可以接收prevNodenextNode的值。getPrevNextNodes函數的實現如下:

           getPrevNextNodes(index){
              let count = 0;
              let prevNode = this.head;
              let nextNode = prevNode.next;
          
              while(count < index - 1){
                prevNode = prevNode.next;
                nextNode = prevNode.next;
                count++;
              }
          
              return {
                prevNode,
                nextNode
              }
            }
          

          通過遍歷鏈表返回在index-1位置和index位置的節點,并將prevNodenext屬性指向新節點,并將新節點的next屬性指向nextNode

          鏈表的插入操作的復雜度為 O(n),因為我們必須遍歷鏈表并在index-1index 位置搜索節點。盡管復雜度為O(n),但我們發現此插入操作比對數組的插入操作快得多,在數組中,我們必須將所有元素的索引移到特定索引之后,但是在鏈接中,我們僅操縱 index-1index 位置的節點的下一個屬性。

          remove (刪除特定索引處的元素)

          實現了插入操作之后,刪除操作就比較容易理解,因為它幾乎與插入操作相同,當我們從getPrevNextNodes函數獲取prevNodenextNode值時,我們必須在remove中執行以下操作:

          remove(index){
            let {previousNode,currentNode} = this.getNodes(index)
            previousNode.next = currentNode.next
            this.length--
          }
          

          刪除操作的復雜度也為 O(n),類似于插入操作,鏈表中的刪除操作比數組中的刪除操作要快。

          reverse (反轉鏈表)

          雖然看起來很簡單,但反轉鏈表常常是實現起來最令人困惑的操作,因此,在面試中會經常詢問這個操作。在實現這個函數之前,讓我們先把反轉鏈表的策略可視化一下。

          為了反轉鏈表,我們需要跟蹤三個節點,previousNodecurrentNodenextNode

          考慮下面的鏈表:

          let linkedList2 = new LinkedList()
          linkedList2.append(67)
          linkedList2.append(32)
          linkedList2.append(44)
          

          第一步:

          開始,previousNode的值為null,而currentNode的值為head

          第二步:

          接下來,我們將nextNode分配給currentNode.next

          第三步:

          接下來,我們將currentNode.next屬性指向previousNode

          第三步:

          現在,我們將previousNode移至currentNode,將currentNode移至nextNode

          這個過程從步驟2重復操作,一直到currentNode 等于 null

          reverse (){
            let previousNode = null
            let currentNode = this.head
          
            while(currentNode !== null) {
              let nextNode = currentNode.next
              currentNode.next = previousNode
              previousNode = currentNode
              currentNode = nextNode
            }
          
            this.head = previousNode
          }
          

          就像我們看到的一樣,直到currentNode===null,我們一直在遍歷和移動這些值。最后,我們將previousNode值分配給head

          反向運算的復雜度為O(n)

          查找 (查找特定索引的值)

          這個操作很簡單,我們只是遍歷鏈表并返回特定索引處的節點。這個操作的復雜度也是O(n)

          lookup(index){
              let counter = 0;
              let currentNode = this.head;
              while(counter < index){
                currentNode = currentNode.next;
                counter++;
              }
              return currentNode;
            }
          

          好了,我們已經完成了用javascript實現單個鏈表的基本操作。單鏈表和雙鏈表的區別在于,雙鏈表的節點具有指向前一個節點和下一個節點的指針。

          總結

          鏈表為我們提供了快速的append(末尾添加元素)和prepend(開頭添加元素)操作。盡管鏈表中的插入操作的復雜度為O(n),但比數組的插入操作要快得多。使用數組時我們面臨的另一個問題是大小復雜性,當使用動態數組時,在添加元素時,我們必須將整個數組復制到另一個地址空間,然后添加元素,而在鏈表中,我們不需要 面對這樣的問題。

          在使用對象時,我們面臨的問題是元素在內存中的隨機位置,而在鏈表中,節點是通過指針相互連接的,指針提供了一定的順序。

          我是小智,我們下期見!


          作者:Vivek Bisht 譯者:前端小智 來源:soshace

          原文:https://blog.soshace.com/understanding-data-structures-in-javascript-linked-lists/


          主站蜘蛛池模板: 国产一区视频在线| 亚洲AV无码一区东京热久久| 国产在线观看一区精品| 在线观看一区二区三区av| 中文字幕国产一区| 无码人妻aⅴ一区二区三区| 韩日午夜在线资源一区二区| 国产福利一区二区精品秒拍| 亚洲AV噜噜一区二区三区| 无码一区二区三区老色鬼| 国产福利电影一区二区三区,日韩伦理电影在线福 | 国产成人无码aa精品一区| 久久久久人妻一区二区三区| 日本激情一区二区三区| 亚洲福利秒拍一区二区| 日韩一区二区在线观看视频| 国产一区二区三区乱码| 激情内射日本一区二区三区| 一区二区三区在线播放视频| 亚洲午夜精品第一区二区8050| 精彩视频一区二区| 亚洲日本一区二区三区在线不卡| 国产一区在线观看免费| 变态调教一区二区三区| 一区二区精品在线观看| 国产激情一区二区三区| 国产综合一区二区在线观看| 国产一区二区三区免费观看在线| 亚洲国产精品成人一区| 一本AV高清一区二区三区| 精品视频一区二区三区在线观看| 亚洲国产精品一区第二页| 精品无码日韩一区二区三区不卡| 亚洲综合色一区二区三区小说| 亚洲av综合av一区二区三区| 天堂Av无码Av一区二区三区| 日本丰满少妇一区二区三区| 中文字幕一区精品| 久久精品一区二区三区日韩| 中文字幕精品一区二区| 国产凸凹视频一区二区|