首頁 > web前端 > js教程 > 主體

關於 JavaScript 你可能不知道的六件事

Mary-Kate Olsen
發布: 2024-10-22 06:18:03
原創
428 人瀏覽過

作者:路易斯·西安奇✏️

那麼,您是 JavaScript 開發人員?很高興聽到 - 你認為這段程式碼會回傳什麼?是的,這是一個棘手的問題:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

在幾乎任何其他語言中——C#、Java,這樣的例子不勝枚舉——我們可以使用 JavaScript Expert 取回物件。如果您認為在 JavaScript 中我們會得到相同的結果,這是可以理解的。

不過,請幽默一下,並將其彈出到您的開發控制台中,然後執行該函數。幾乎令人難以置信的是,它返回未定義。

當事情沒有照計劃進行時

作為軟體開發人員工作意味著您要對應用程式的工作方式負責,無論它運作得好還是不好。其中的一個主要限制是您決定使用的工具。如果您了解自己正在使用什麼,那麼您預計將在設計軟體時做出正確的選擇。

JavaScript 是獨一無二的,因為它是許多新軟體開發人員選擇的語言。想編寫行動應用程式嗎?只需使用 React Native 和 JavaScript。桌面應用程式? React Native 和 JavaScript。在某個地方運行的雲函數? Node.js,你猜對了,還有 JavaScript。

然而,由於 JavaScript 已經存在了很長一段時間,它也有不少的問題和陷阱。其中一些問題的範圍從輕微有趣到我的程式碼不起作用且我不知道為什麼嚴重。

而且,即使我們生活在 Internet Explorer 6 全盛時期,嘗試修復其中一些設計決策也為時已晚,因為我們會破壞太多的網路。如果當時情況確實如此,想像一下我們今天是否嘗試過! ??

那麼,JavaScript 為何沒有按照我們預期的方式運作呢?我們來看看吧。

自動分號注入 (ASI)

開頭列出的範例被 JavaScript 解釋器接受,但沒有產生預期的結果。原因是自動分號注入。

某些語言(例如 C#)教條地規定以分號結束每一行。 JavaScript 也使用分號來表示行尾,但分號實際上是可選的。可選的,這意味著 JavaScript 將應用一組複雜的規則來確定分號是否應該出現在那裡。

在一開始的範例中,由於左括號與回車符不在同一行,因此 ASI 會在其中彈出一個。所以,就 JavaScript 而言,我們的程式碼實際上是這樣的:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

避免這種情況的方法是將左括號與回車符放在同一行。而且,雖然分號在 JavaScript 中在技術上是可選的,但從長遠來看,使用這個概念會給你帶來傷害。

如果你有一個面試,你必須寫JS,並且你基於「但它們是可選的」的理由而沒有分號地寫它,那麼將會有很多文件拖沓和咯咯笑。只是不要這樣做。

具有非順序鍵的數組

假設我們有一個簡單的陣列:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

我們知道我們可以對陣列進行彈出、推送、追加等操作。但我們也知道,JavaScript 與其他語言一樣,允許我們透過索引存取陣列元素。

然而,JavaScript 的不尋常之處在於,當數組還沒有達到該索引時,您還可以透過數組索引設定元素:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

不過,我有一個很好的問題想問你-當你只設定三個元素時,陣列的長度是多少?可能不直觀,它是 101。一方面,數組項 2 到 99 未定義是合理的,但另一方面,我們只設定了三個對象,而不是 100。

為什麼重要?
也許你的眼睛會從你的腦袋裡滾出來,你會說「好吧,劉易斯,你正在手動將項目分配到一個數組中,然後看著輪子脫落;這讓你感到奇怪,而不是 JavaScript」。

我會理解這個立場。但想像一下,您正在嵌套的 for 迴圈中執行某些操作,並且選擇了錯誤的迭代器或進行了無效計算。

在某些時候,「為什麼我得到預期結果,預期結果,未定義,預期結果」的思考過程將變得瘋狂,很快就會流淚!您幾乎不知道您的陣列會神奇地成長以適應您想要做的事情。

唯一的問題是,你試著做錯誤的事情。

與 C# 等其他語言相比(沒有特殊原因),陣列是固定長度的。建立數組時,必須定義長度。即使是其他動態集合物件(例如 List),您也無法指派到未定義的索引中。因此,如果您的巢狀循環嘗試寫入先前未分配的索引,您的程式將拋出異常。

例外並不好,但這可能是正確的做法。我的意思是,你是否打算創建一個瑞士起司陣列?有人打算這樣做嗎?但願不會。  

Six things you may not know about JavaScript 如果開發人員來自瑞士,那麼它只是瑞士起司陣列。否則,這只是閃閃發光的糟糕程式。

向基元添加屬性將被忽略

我們知道在 JavaScript 中我們可以將新函數指派給原型。所以,我們可以賦予字串或陣列✨特殊的力量✨。當然,這樣做是糟糕的做法,因為這意味著我們的字串原型的行為將與其他字串原型不同,這已經給許多開發人員帶來了難以言喻的心痛。

所以,我們可以這樣做:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

然後我們可以建立一個字串物件:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

並且它會回傳 false。

很可愛的是,我們總是可以將我們的函數隨機地塞入工廠定義的字串如何操作的實作中。

當然,所有這些好人都竭盡全力,花了數萬個小時在 TC39 規範中定義 JavaScript,但不要因此而阻止您按照自己認為合適的方式修改隨機函數。

如果我們對那種特定的痛苦不滿意,我們也可以根據需要隨機地將新函數分配給複雜的對象,確保我們的代碼將是一種非常特殊的無意義形式,只有你自己和上帝才能理解:
Six things you may not know about JavaScript
像這樣組合我們的物件自然是一個糟糕的主意,但是當我們致力於這種背叛時,JavaScript 就滿足了我們的要求。我們的 testObject 承擔了我們投入的新功能。

然而,善意卻以一種令人驚訝的方式耗盡了對象原語:
Six things you may not know about JavaScript
解釋器承認我們嘗試將函數分配給字串基元。它甚至將這個函數回顯給我們。但是,當我們嘗試呼叫它時,我們得到一個 TypeError:testString.onlyFalse 不是一個函數。如果不可能做到這一點,通常您會期望它在賦值時拋出,而不是在函數呼叫時拋出。

為什麼重要?
無論好壞,JavaScript 都是一種高度靈活且動態的語言。這種靈活性使我們能夠編寫其他語言無法實現的功能。如果某些事情不起作用,那麼我們應該期待一個例外。 JavaScript 接受這個尷尬的命令並表示“呃,好吧”,然後忘記它改變了這個基本期望。

類型強制

在其他強類型語言中,我們必須先定義要儲存的資料的類型,然後才能儲存資料。 JavaScript 沒有這種同樣的限制,它會很樂意將物件從其定義的類型中推開,試圖讓它們很好地協同工作。

一方面,它讓我們不必將變數來回轉換為各自的型別。所以很方便:Six things you may not know about JavaScript
布林值也是如此:
Six things you may not know about JavaScript
這種方法是完全理性和有效的,直到我們想要參與被稱為「加法」的禁忌儀式。當我們嘗試將“1”和 1 加在一起時,會發生什麼?類型強制是怎樣進行的?
Six things you may not know about JavaScript
當我們把 bool 帶到聚會上時,瘋狂歡鬧會倍增:
Six things you may not know about JavaScript
喔——是因為 bool 在某種程度上是一個數字嗎?
Six things you may not know about JavaScript不。這是一個布林值。由於某些原因,JavaScript 正在剃掉正方形的討厭邊緣,以將其裝入圓孔中。

為什麼重要?
當你做一些像是將數字相加這樣的基本事情時,結果不同可能會產生一些奇怪的錯誤。這是一個很好的提醒,在進行比較時要堅持使用三等號 (===),因為在類型之間切換可能不會給您預期的結果。

功能吊掛

對於我們今天使用的語言,一個重要的方面是所謂的「函數提升」。本質上,這意味著您可以將函數寫入檔案中的任意位置,並且可以在聲明函數之前呼叫它們:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

這很方便,因為我們不必手動重新排序程式碼即可使其工作。

但是,描述函數的方法不只一種。在此範例中,我們使用函數聲明來執行此操作。我們也可以使用函數表達式:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登入後複製
登入後複製
登入後複製
登入後複製

為什麼重要?
在這兩種情況下聲明函數之間沒有很大的區別,但如果你選擇了錯誤的函數,你將無法呼叫你的函數,除非你在聲明它之後呼叫它。

空是一個對象

在其他語言中,物件屬性可以被賦值,也可以為空。 null 表示該屬性未指派。在我們的頭腦中很容易等同——那裡要么有一個對象,要么它是空的。如果我們願意,我們也可以將屬性指派回 null。

JavaScript 透過使用 null 和未定義來使這種情況變得複雜。但都是一樣的,對吧?你要么手裡有球,要么沒有。

毫不奇怪,並不完全相同。在 JavaScript 中,null 表示有意缺少值,而 undefined 表示隱含缺少值。所以,無論是故意的、明確的,還是天上寫的,事實就是沒有價值=沒有價值,對吧?

不幸的是,這又不是等式的計算方式。

那麼,undefined 是什麼類型呢?
Six things you may not know about JavaScript

好的,那麼 null 的型別是什麼?
Six things you may not know about JavaScript

?它是一個物體。所以在 JavaScript 中,複雜物件和 null 的型別是相同的-它們都是物件:
Six things you may not know about JavaScript

為什麼重要?
JavaScript 沒有內建強大的類型檢查系統,並且只有少數基本類型可供選擇。因此,使用 typeof 來理解變數中的內容可能會變得很棘手。如果我們的變數保存一個有效的對象,那麼我們就會得到對象。但如果它為空,我們仍然會得到物件。認為空引用是一個物件是違反直覺的。

結論

毫無疑問,JavaScript 作為一種語言如今非常受歡迎。隨著時間的推移,npm 等其他生態系統繼續託管大量軟體包,JavaScript 只會繼續流行。

但是事情已經過去了。無論 null 是物件有多奇怪,或者 JavaScript 會在它認為合適的地方彈出分號,這些系統可能永遠不會被棄用、更改或刪除。有趣的是,我想說,如果自動分號注入在一夜之間關閉,它可能會導致比 CrowdStrike 更新更大的全球中斷。

當然,更改其中一項會對網路造成嚴重破壞。實際上,讓開發人員意識到這些特定的語言怪癖比實際返回並解決原始問題更安全,也可能更實用。

所以,去做正確的選擇,別忘了使用分號!


LogRocket:透過了解上下文更輕鬆地調試 JavaScript 錯誤

偵錯程式碼總是一項乏味的任務。但你越了解自己的錯誤,就越容易糾正它們。

LogRocket 讓您以新的、獨特的方式理解這些錯誤。我們的前端監控解決方案追蹤使用者與 JavaScript 前端的互動,使您能夠準確查看使用者的操作導致了錯誤。

Six things you may not know about JavaScript

LogRocket 記錄控制台日誌、頁面載入時間、堆疊追蹤、帶有標頭正文的慢速網路請求/回應、瀏覽器元資料和自訂日誌。了解 JavaScript 程式碼的影響從未如此簡單!

免費試用。

以上是關於 JavaScript 你可能不知道的六件事的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!