程式設計師必須掌握的 12 個 JavaScript 技能!

2021-01-11 CSDN

本文論述的12個概念,對於 JavaScript 開發者來說都是非常重要的。

作者 | Nick Scialli

譯者 | 譚開朗

責編 | 屠敏

以下為譯文:

JavaScript 是一種複雜的程式語言。無論你的開發水平如何,理解 JavaScript 的基礎概念都尤為重要。

本文將與大家分享 12 個實用的 JavaScript 技能,未來我也將在 Github 的 JS Tips&Tidbits 倉庫(https://github.com/nas5w/javascript-tips-and-tidbits)中持續更新此概念列表。

值和引用變量的賦值

理解 JavaScript 的賦值原理是正確編碼的基礎,否則,很容易在編碼過程中無意篡改值。

JavaScript 通常是通過值來賦值變量。但需要注意一點:JavaScript 基本數據類型(布爾值、null、undefined、字符串和數字)的賦值是拷貝賦值,而數組,函數或對象的賦值是引用賦值。

舉個例子。下面的代碼,把 var1 賦值給 var2。因為 var1 是基本數據類型(字符串),所以 var2 等於 var1 的字符串值,或者說 var2 全等於 var1。因此,給 var2 重新賦值不會影響到 var1。

let var1 = 'My string';let var2 = var1;var2 = 'My new string';console.log(var1);// 'My string'console.log(var2);// 'My new string'

讓我們對比一下給對象賦值。

let var1 = { name: 'Jim' }let var2 = var1;var2.name = 'John';console.log(var1);// { name: 'John' }console.log(var2);// { name: 'John' }

如果還像上面那樣原始賦值,就出現問題了。如果創建了一個會篡改值的函數,那情況將會更糟糕。

閉包

閉包是一種重要的 JavaScript 模式,用於對變量進行私有訪問。如下例子中,createGreeter 函數返回一個能訪問 greeting 值為「Hello」的匿名函數。往後每引用一次 sayHello 變量都會訪問該 greeting 值。

functioncreateGreeter(greeting) {returnfunction(name) {console.log(greeting + ', ' + name); }}const sayHello = createGreeter('Hello');sayHello('Joe');// Hello, Joe

在更真實的案例場景中,假設一個初始函數 apiConnect(apiKey) 返回一些引用 API key 的方法。在這種情況下,初始函數的內部參數 apiKey 只需賦值一次,往後無需重新賦值。

functionapiConnect(apiKey) {functionget(route) {return fetch(`${route}?key=${apiKey}`); }functionpost(route, params) {return fetch(route, {method: 'POST',body: JSON.stringify(params),headers: {'Authorization': `Bearer ${apiKey}` } }) }return { get, post }}const api = apiConnect('my-secret-key');// No need to include the apiKey anymoreapi.get('http://www.example.com/get-endpoint');api.post('http://www.example.com/post-endpoint', { name: 'Joe' });

解構

別忘了學習 JavaScript 參數的解構賦值。這是一種簡潔地提取對象屬性的通用方法。

const obj = {name: 'Joe',food: 'cake'}const { name, food } = obj;console.log(name, food);// 'Joe' 'cake'

要想提取不同名的屬性,可以使用以下格式來指定它們。

const obj = {name: 'Joe',food: 'cake'}const { name: myName, food: myFood } = obj;console.log(myName, myFood);// 'Joe' 'cake'

在下面的例子中,解構簡潔地向 introduce 函數傳遞 person 對象參數。換言之,解構可以(通常用來)直接提取參數同時傳遞給一個函數。如果你熟悉 React,那很可能在之前就見到過此用法。

const person = {name: 'Eddie',age: 24}functionintroduce({ name, age }) {console.log(`I'm ${name} and I'm ${age} years old!`);}console.log(introduce(person));// "I'm Eddie and I'm 24 years old!"

展開語法

展開語法是個比較難理解的 JavaScript 概念,叫擴展運算符會相對容易理解。在下面的例子中,Math.max 方法不會作用於數組 arr,因為 Math.max 方法的參數只能是單個元素而不能是一個數組。擴展運算符可以從數組中提取出單個元素。

const arr = [4, 6, -1, 3, 10, 4];const max = Math.max(...arr);console.log(max);// 10

剩餘語法

讓我們來談談 JavaScript 的剩餘語法。剩餘語法可以通過一個函數將任意數量的參數收集到一個數組中。

functionmyFunc(...args) {console.log(args[0] + args[1]);}myFunc(1, 2, 3, 4);// 3

數組方法

JavaScript 數組方法可以神奇且優雅的進行數據轉換。作為 StackOverflow 的貢獻者之一,我經常看到關於如何用某種方法操作數組對象的問題。這往往是數組方法的最佳用例。

我將在這裡用類似的表達方式(某些已合併在內)來介紹多種不同的數組方法。以下羅列的方法並不全面:你也可以參考 MDN(我喜愛的 JavaScript 參考資料:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#)回顧和實踐所有方法。

map, filter, reduce

JavaScript 的 map、filter、reduce 數組方法很容易被混淆。這些方法是用來轉換數組或者返回值的集合。

map:將調用的數組的每個元素傳遞給指定的函數,並返回一個數組。const arr = [1, 2, 3, 4, 5, 6];const mapped = arr.map(el => el + 20);console.log(mapped);// [21, 22, 23, 24, 25, 26]

filter:返回的數組元素是函數邏輯為真的一個子集。const arr = [1, 2, 3, 4, 5, 6];const filtered = arr.filter(el => el === 2 || el === 4);console.log(filtered);// [2, 4]

reduce:按函數方法計算值。const arr = [1, 2, 3, 4, 5, 6];const reduced = arr.reduce((total, current) => total + current);console.log(reduced);// 21

find, findIndex, indexOf

JavaScript 的 find, findIndex, indexOf 數組方法通常被合併。用法如下。

find:返回與指定條件匹配的第一個元素,不再往後匹配。const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];const found = arr.find(el => el > 5);console.log(found);// 6

再次注意,(上面的例子中)雖然5以後的所有值都符合條件,但也只返回第一個匹配的元素。這在 for 循環中匹配某個條件後便跳出循環的情況下非常有用!

findIndex:和 find 用法相同,不過不是返回第一個匹配的元素,而是返回該匹配元素的索引值。為清晰可見,以下面的名字數組為例,而不是數字數組。const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr.findIndex(el => el === 'Frank');console.log(foundIndex);// 1

indexOf:和 findIdex 用法相同,但它不以函數作為參數,它的參數是一個簡單的值。適用於簡單邏輯或不需要要函數進行判定的情況。const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr.indexOf('Frank');console.log(foundIndex);// 1

push, pop, shift, unshift

有很多很棒的數組方法可以給目標數組添加或刪除元素。

push:這是一種將元素添加至數組末尾的相對簡單的方法。它修改數組值,函數本身返回壓入數組的值。let arr = [1, 2, 3, 4];const pushed = arr.push(5);console.log(arr);// [1, 2, 3, 4, 5]console.log(pushed);// 5

pop:刪除數組的最後一個元素。同樣,它改變了原數組。函數本身返回被刪除元素的值。let arr = [1, 2, 3, 4];const popped = arr.pop();console.log(arr);// [1, 2, 3]console.log(popped);// 4

shift:從數組頭部刪除一個元素。同樣,它改變了原數組。函數本身返回被刪除元素的值。let arr = [1, 2, 3, 4];const shifted = arr.shift();console.log(arr);// [2, 3, 4]console.log(shifted);// 1

unshift:在數組頭部添加一個或多個元素。同樣,它改變了原數組。與其他很多方法不同的是,函數本身返回數組新的長度。let arr = [1, 2, 3, 4];const unshifted = arr.unshift(5, 6, 7);console.log(arr);// [5, 6, 7, 1, 2, 3, 4]console.log(unshifted);// 7

splice, slice

這兩個方法都是修改數組子集或返回數組子集。

splice:通過刪除或替換現有元素和/或添加新元素改變數組的值。此方法會改變原數組。下面的示例代碼解讀為:從第1位數組元素開始,往後移除0個元素,同時插入 b 值。

let arr = ['a', 'c', 'd', 'e'];arr.splice(1, 0, 'b')

slice:返回從指定的起始位置到結束位置的淺拷貝數組。如果沒有指定結束位置,則會返回到原數組的最後部分。重要的是,該方法不會改變原數組的值,而是返回對應的子集。let arr = ['a', 'b', 'c', 'd', 'e'];const sliced = arr.slice(2, 4);console.log(sliced);// ['c', 'd']console.log(arr);// ['a', 'b', 'c', 'd', 'e']

sort

sort:根據帶兩個參數的函數對數組進行排序。改變原數組的值。當函數返回負數或0,則數組元素順序不改變。當函數返回正數,數組元素會重新排序。let arr = [1, 7, 3, -1, 5, 7, 2];const sorter = (firstEl, secondEl) => firstEl - secondEl;arr.sort(sorter);console.log(arr);// [-1, 1, 2, 3, 5, 7, 7]

嘿,以上方法你都掌握了嗎?或許我們都沒有。實際上,在我寫本篇文章時夜不得不時常查閱 MDN 文檔,這很正常。只要知道有什麼數組方法就達到 95% 的效果啦。

Generators 函數

不要害怕使用 * 函數。Generator 函數指定了下一次調用 next() 生成的 value 值。在有限個生成值或無限次循環下使用,最後 next() 會返回一個 undefined 值。

function* greeter() {yield'Hi';yield'How are you?';yield'Bye';}const greet = greeter();console.log(greet.next().value);// 'Hi'console.log(greet.next().value);// 'How are you?'console.log(greet.next().value);// 'Bye'console.log(greet.next().value);// undefined

下面是一個無限值的 Generator 函數:

function* idCreator() {let i = 0;while (true)yield i++;}const ids = idCreator();console.log(ids.next().value);// 0console.log(ids.next().value);// 1console.log(ids.next().value);// 2// etc...

恆等運算符和相等運算符

一定要知道 JavaScript 中恆等運算符和相等運算符之間的區別!相等運算符在比較值前允許進行類型轉換,而恆等運算符則不允許類型轉換。

console.log(0 == '0');//trueconsole.log(0 === '0');//false

比較對象

JavaScript 新手常犯的錯誤之一是對對象直接進行比較。變量是指向內存中的引用對象,而不是對象本身!實際比較它們的一種方法是將對象轉換成 JSON 字符串。這種方法有個缺點:不能保證對象屬性的順序!比較對象更安全的方法是使用專門用於深度對象比較的庫(比如 lodash 庫的 isEqual 方法)。

下面這兩個對象看起來相等,但實際上它們指向不同的引用對象。

const joe1 = { name: 'Joe' };const joe2 = { name: 'Joe' };console.log(joe1 === joe2);// false

相反地,下面的計算結果返回 true,因為把一個對象賦值給另一個對象,它們的指向相同(內存中只有一個對象)。

const joe1 = { name: 'Joe' };const joe2 = joe1;console.log(joe1 === joe2);// true

請回顧上面的第一個概念:值和引用變量的賦值,將有助於更系統的理解將指向內存的一個對象變量賦值給另一個變量的結果。

回調函數

太多人被 JavaScript 的回調函數嚇倒了。回調函數很簡單,舉下面這個例子。將 console.log 作為回調函數傳給 myFunc 函數,它在計時器 setTimeout 完成時執行。這就是回調函數的全部!

functionmyFunc(text, callback) { setTimeout(function() { callback(text); }, 2000);}myFunc('Hello world!', console.log);// 'Hello world!'

Promises

一旦你理解了 JavaScript 的回調函數,你很快就發現自己陷入了嵌套的「回調地獄」。這就是 Promises 的用途。將異步邏輯封裝在 Promise 中,異步操作執行成功則運行 resolve 回調函數,否則則運行 reject 回調函數。Promise 運行成功進入 then 回調函數,失敗則進入 catch 回調。

const myPromise = newPromise(function(res, rej) { setTimeout(function(){if (Math.random() < 0.9) {return res('Hooray!'); }return rej('Oh no!'); }, 1000);});myPromise .then(function(data) {console.log('Success: ' + data); }) .catch(function(err) {console.log('Error: ' + err); });// If Math.random() returns less than 0.9 the following is logged:// "Success: Hooray!"// If Math.random() returns 0.9 or greater the following is logged:// "Error: On no!"

Async Await

一旦掌握了 JavaScript Promises 的秘訣,你可能會喜歡 async await,這是基於 Promises 的「語法糖」。在下面的例子中,我們創建一個異步函數 myFunc,並在函數中等待執行 greeter 這一 promise。

const greeter = newPromise((res, rej) => { setTimeout(() => res('Hello world!'), 2000);})asyncfunctionmyFunc() {const greeting = await greeter;console.log(greeting);}myFunc();// 'Hello world!'

結論

如果你以前完全不知道以上這 12 個概念,那麼現在,你的 JavaScript 知識多少有些增長了!如果你知道所有這些,那麼希望這是鞏固和增長知識的機會。

原文:https://hackernoon.com/12-javascript-concepts-that-will-level-up-your-development-skills-b37d16ad7104本文為 CSDN 翻譯,如需轉載,請註明來源出處。

相關焦點

  • 七天學會javascript第一天javascript介紹
    前幾周寫了幾篇關於入門php的文章,反響還不錯,之前簡單的提到了JavaScript,這周小編重點介紹JavaScript讓大家可以在一周時間內掌握這門前端語言的基本用法。javascript介紹javascript數據類型javascript運算符javascript對象javascript Date對象javascript String對象JavaScript常用於實現一些前端效果。前些年流行的flash已經慢慢的被淘汰,js盛行起來。javascript :客戶端編程。javascript是由客戶端去解釋運行的。
  • javascript在自動化測試項目中的應用「軟體測試開發入門教程」
    因為最近我看到拉勾網和Boss直聘上面有個大數據,現在不是大數據時代嗎?這一類大型招聘網站,給我們軟體測試行業發了一個文章,就是軟體測試從業者大概的一個現狀現在軟體測試從業迎來了一個危機,是什麼呢。就是說這一類的人員非常稀缺,十個測試有八個初中級,可能就是傳統的功能測試,可能有一兩個是自動化測試高級,測試開發高級。如果你去聽一些自動化測試,測試架構直播公開課,覺得有一些太深的知識點很茫然,聽不懂的朋友有沒有考慮過是自己的問題,該充電了。
  • 高級SEM專員必須掌握的7項技能!
    優秀的SEM專家需要掌握哪些能力?百度競爭者到底在幹什麼?做百度競價,我需要掌握什麼技能?……………來到這裡,根據自己的經驗,總結了高級SEM專員必須掌握的7項技能,供參考。2.掌握流量思維市場營銷的本質是交流,但並不是說在意的交流。我們真正需要的是在正確的時間和正確的人說正確的話。這需要我們把握流量的思考。畢竟百度競爭價格是一個用錢奪取流量的過程。既然花了錢,我們就值得花掉所有的錢!
  • 程式設計師是做什麼的?未來計算機變得智能,就不需要程式設計師了嗎?
    在人類和計算機之間的翻譯 翻譯中會遇到三個主要的挑戰: 人類習慣於思考需求、結果與解決方案之間的關係,例如:「這份報告應該在2秒內運行,而不是2個小時」。然而,計算機需要算法——按照步驟去達到想要得到的結果。 為了寫出優秀的軟體,程式設計師們必須克服這些困難,理解人們的想法並將之轉換成計算機語言。
  • 每一位小白程式設計師都應學會的 3 項技能
    在最近的一次訪談中,Joel Spolsky(StackOverflow的聯合創始人)表示,一個新從事編程工作的小白需要學會3項技能:經濟學、寫作和C語言。
  • 專科VS本科:別給專科程式設計師套上學歷的枷鎖!
    專科程式設計師的職業歷程可能如下: 剛畢業去了小公司(或者外包); 年後跳稍微好點的小公司(創業團隊); 接著技能逐漸完善; 開始在小公司挑大梁(或者進入中型企業); 為了漲薪繼續跳槽。
  • javascript語言的六大運算符功能,你掌握了多少?
    記得昨天小編說過,想要成為一名優秀的程式設計師,基礎最重要,看一遍,不如打開編輯工具,編一遍,打開筆記本,抄一遍。想成為編程大咖的你,照做了嗎?對於昨天的數據轉換,你掌握了多少?好了,廢話就不多講了,咱們開始今天的新旅程吧!今天小編要給大家分享的是JS的運算符與及運用,那麼問題來了,什麼是JS運算符呢?
  • 前端Web開發人員應 該具備的十大技能,你掌握了幾個?
    #web前端#前端Web開發是當今技術行業中最需求的技能之一。隨著新技術的創新,該行業不斷變化。因此,開發人員需要跟上變化。什麼是前端Web開發人員?前端Web開發人員是創建用戶在網頁上看到並與之交互的設計和元素的Web開發人員。
  • 要掌握哪些技能
    要掌握哪些技能?在Java程序界流行著一種默認的說法叫「黃金5年」,也就是一個程式設計師從入職的時候開始算起,前五年的選擇直接影響著整個職業生涯中的職業發展方向和薪資走向。這幾年在大數據的影響下,Java大數據開發的熱度也是居高不下。
  • 50%是招聘,50%是培訓,100%是程式設計師
    程式設計師水平究竟如何,與崗位要求是否契合,不一定能通過面試環節檢驗出來。 在美國,亞馬遜、Facebook等公司已在採用一種新的程式設計師招聘方式,更注重「技能優先」,考察面試者在算法、數據結構方面的功底,而不是「簡歷優先」。在這種模式下,企業會對應聘者進行在線測評、白板面試等多種形式的技術能力評估,佔比達到了整個環節的70%,這其中主要使用了力扣的題目。
  • 第41節 Document文檔節點-Javascript
    能方便地獲取到任意文檔的根元素;body屬性:作為HTMLDocument的實例,document對象還有一個body屬性,直接指向<body>;console.log(document.body);對於一個擁有<frameset>元素的文檔來說,返回的是最外層的<frameset>元素;另外,該屬性是可寫的,且為該屬性賦的值必須是一個
  • 高級程式設計師是如何從初級程式設計師演變的?工作經驗不再是唯一途徑!
    在工作的那些年裡你到底獲得了多少經驗和技能?這正是面對開發人員的求職和面試如此複雜的原因。度量技能是很困難的,所以我們在面試中給開發人員進行了很多有難度的測試。但這些測試充其量也只是了解一個大概,無法度量其究竟具備多少完成該項工作所需的經驗或專業技能。 這就引出了下一個問題。
  • 被嫌棄的35歲程式設計師
    一位 35+ 程式設計師在求職網站自述,他在今年年初被裁後的 2 個月裡,瘋狂海投簡歷、面試,只拿到了 6 個非大廠 offer,最終他決定平薪入職其中一家。打擊面並不僅限於職場。在某社交平臺上,一位程式設計師憤憤表示,新認識的交友對象對「程式設計師到了 35 歲就退休」的定律感到介意,以致於感情快告吹了。
  • JavaScript - Math對象
    Math對象在我們js中其實是有很多數學計算的需求的,不過不必擔心系統給我們提供了大量的數學運算的方法供我們使用而這些方法全都存在於我們的Math對象中Math常用的屬性:Math.PI 相當於π 3.14159Math對象常用的函數:1.Math.round() 四捨五入舉個小例子
  • JavaScript正則表達式「程式設計師培養之路第十二天」
    圖一第二節 創建正則表達式通過new運算符定義RegExp是一個對象,可以通過new運算符聲明一個正則表達式:var re = new RegExp("a","i");//這是個最簡單的正則表達式,將匹配字母a,第二個參數i,表示匹配時不分大小寫字面量定義//全文匹配abcvar re=/abc/g; 注意: 正則表達式內不要出現空格(除非想匹配空格)
  • 程式設計師必備的50個快捷鍵,提升效率必備!
    每天工作都和電腦打交道,所以掌握一些常用的電腦快捷鍵很重要,尤其是程式設計師,工作上效率,質量,速度少一個都不行。而使用快捷鍵能讓他們在工作時更高效,更速度!下面就和大家分享50個程式設計師必備電腦快捷鍵,幫你提升工作效率100倍!
  • JavaScript入門教程
    起源javascript前身叫做livescript,sun公司推出java,netspace公司引進java的概念,重新設計livescript,並更名javascript。發明者,布蘭登.艾克,表單驗證原先要經過伺服器,伺服器壓力大,等待時間長,js僅在客戶端就可完成。是什麼是一種腳本語言,是一種輕量級的程式語言。
  • 初中學歷可以轉行做程式設計師?
    初中學歷可以轉行做程式設計師,但是能否有更好的發展很難說。我本人普通本科畢業,做了六年程式設計師,而且我本科期間所學專業也不是計算機,後來成為程式設計師也是自學轉行的,自認為轉行做程式設計師並不難。雖然題主你目前只有初中學歷,但是想成為程式設計師其實也不難,以我的經驗,只要26個英文字母認得全,有一點英語基礎,去培訓機構培訓三個月,基本就能寫程序,成為一名初級程式設計師。
  • 對於程式設計師來說,技術深度與廣度哪個更重要一點?
    對於大多數程式設計師來說,都有自己的主要技術領域,主要在某固定的領域內做事,全棧的工程師相對來說比較少一點,畢竟每個人的精力是有限的,不可能同時掌握多個領域,如果掌握的廣度上大一點,可能深度上就相對會弱一點,當然,也不一定這麼的絕對,這還是要看個人的學習精力了,那麼對於程式設計師來說,技術深度與廣度哪個更重要的
  • Javascript去除字符串中的點或其他符號
    在前端上使用javascript進行操作的。測試了兩次沒有好用,程序直接把整個字符串都進行了替換,在考慮這個是為什麼呢?javascript(請忽略此配圖)示例var ip = data.field.ip.replace(/.