JavaScript 初學者容易犯的幾個錯誤,你中招沒?

JavaScript 是對初學者比較友好的一門編程語言,基本上花個半小時看下語法就能寫出能運行的代碼。JavaScript 是動態腳本語言,對數據類型沒有太多的限制,寫起來很是靈活。但正由於如此,初學者若是不深刻了解語言自己,每每會犯一些錯誤,從而致使一些很難發現的 bug。

拋開 JavaScript 語言設計層面的問題不說,畢竟它是 Brendan Eich 當年用短短十天時間設計出來的,有點缺陷也是在所不免。做爲開發者,咱們該怎樣避免一些常見的低級錯誤呢?本文就列舉幾個常見錯誤,看看你有沒有似曾相識。編程

混淆 undefined 和 null

JavaScript 中的undefined 和 null 均可用來表示沒有值,可是兩者之間有所區別。undefined字面意思是「未定義」,但它的含義其實已經超出了變量未定義的範疇:嘗試讀取對象不存在的屬性、沒有return語句的函數的返回值、聲明後沒有賦值的變量甚至顯式賦值爲undefined的變量等,它們的結果都是undefined。用typeof測試它的類型,是字符串 'undefined'。而 null 就比較純粹了,變量只有設置爲null 纔有這個值。另外,null 是對象類型,即typeof(null)的值是字符串'object'數組

須要注意的是,用if判斷這兩個值都是false,並且null==undefined是成立的,這一點初學者一般容易搞混。所以,儘可能統一把「沒有值」都設置爲undefined,這樣就省去了判斷區分的麻煩。bash

返回 undefined的函數:微信

const f = () => {}

複製代碼

設置變量的值爲 undefined編程語言

x = undefined;

複製代碼

判斷屬性是否爲 undefined函數

typeof obj.prop === 'undefined'
obj.prop === undefined

複製代碼

判斷變量是否爲 undefined測試

typeof x === 'undefined'

複製代碼

變量聲明後沒有賦值,自動就有了 undefined值。ui

若是必定要判斷null,用全等判斷:spa

obj.prop === null
x === null
複製代碼

使用 typeof 是沒法判斷 null的,由於它是對象類型。設計

混淆數字相加和字符串拼接

在 JavaScript 中,加號 +操做符既可用於數字相加,也能夠用於字符串拼接。因爲 JavaScript 是動態語言,操做符會自動將變量轉成相同數據類型再運算。好比:

let x = 1 + 1; // 2

複製代碼

結果是 2,是咱們指望的數字相加操做,由於兩個值都是數字。

可是,若是是下面這種表達式:

let x = 1 + '1'; // 「11」

複製代碼

結果是'11',由於第一個數字會轉換成字符串。這裏的加號+運算符被用做字符串拼接,而不是數字相加。這裏能直接看到表達式的值還算清楚,若是是由多個變量組成的表達式就很難判斷類型了。

爲了解決這個問題,咱們能夠把字符串都轉成數字類型,再進行運算。例如:

let x = 1;  
let y = '2';  
let z = Number(x) + Number(y);

複製代碼

這樣,運行結果就是3了。 Number函數接收任意類型的值,若是能轉成數字就返回數字,不然返回NaN。還能夠用 new Number(...).valueOf()函數:

let x = 1;  
let y = '2';  
let z = new Number(x).valueOf() + new Number(y).valueOf();

複製代碼

因爲 new Number(...) 是實例化一個構造函數,返回的是一個對象,並非數字類型。若是要獲得原始的數字類型,須要用該對象的valueOf方法。其實還有個更簡潔的方法:

let x = 1;  
let y = '2';  
let z = +x + +y;

複製代碼

變量前面的 + 做用是將它轉換成數字,或者NaN ,跟Number函數的做用相同。

return 語句換行問題

JavaScript 語法規定換行表明語句結束。例如:

const add = (a, b) => {  
  return  
  a + b;  
}
add(1,2); // undefined
複製代碼

本覺得會返回 3,其實是undefined。這是由於在a + b以前,函數已經執行了return。要解決這個問題,有兩個作法:要麼把表達式跟return放在一行,要麼把表達式套一層括號。

const add = (a, b) => {  
  return a + b;  
}
// 或者
const add = (a, b) => {  
  return (  
    a + b  
  );  
}
複製代碼

加括號爲何能夠換行呢?由於括號裏的是表達式,不是語句。表達式能夠拆成多行,若是很長的話。用箭頭函數會更直觀:

const add = (a, b) => a + b

複製代碼

箭頭函數裏的單行表達式自帶return效果,固然也能夠在表達式外面套一層括號:

const add = (a, b) => (a + b)

複製代碼

這個括號在返回對象字面量的箭頭函數裏有點用處,由於不加圓括號()的話,{}只是函數體的開始和結束標記,要返回對象字面量,還要顯式return {...}

若是某行代碼中的語句不完整,JavaScript 解析器會將下一行的語句合併一塊兒解析。好比:

const power = (a) => {  
  const  
    power = 10;  
  return a ** 10;  
}
// 等同於:
const power = (a) => {  
  const  power = 10;  
  return a ** 10;  
}
複製代碼

可是對於完整的語句,好比return,就不會合並多行。

用 return 跳出 forEach 循環

JavaScript 數組有個 forEach 方法,用於對數組元素進行循環操做。初學者很容易聯想到 for循環的breakcontinue關鍵字,用來停止循環。可是對不起,forEach沒有這兩個關鍵字。那用return行不行?能夠用,但它的做用就是提早返回函數,跟continue的效果相似,用於結束本次循環。要跳出整個循環,return作不到。

const nums = [1, 2, 3, 4, 5, 6];
let firstEven;
nums.forEach(n => {
  if (n % 2 ===0 ) {
    firstEven = n;
    return n;
  }
});
console.log(firstEven); // 6
複製代碼

代碼本意是想找出第一個偶數,找到就退出循環。但實際並無退出循環,所以最終結果是最後一個偶數。 有解決辦法嗎?這種狀況能夠用for循環,或者用數組filterfind之類的方法。

總結

雖然 JavaScript 很容易上手,但稍不注意仍是比較容易犯錯。本文簡單介紹了幾種容易犯的錯,但願對你有所幫助。

有個小小的請求

在掘金已經寫了20多篇技術文章了,承蒙你們厚愛,有過幾篇閱讀數過萬的文章,總閱讀數也突破了10萬。在這裏很是感謝各位的金手指!可是也有個小小的遺憾,每篇文章後面我都留了個人微信公衆號1024譯站二維碼,但不知道爲何關注的人很是少。要是每篇讀者有10%的人來關注,估我計作夢都會笑醒吧,哈哈……像極了小時候的夢想「要是全國每人給我一塊錢,我就有好多個億了!」若是發生了,只能說是個奇蹟。如今我就有這個瘋狂的想法,想邀請你來一塊兒創造這個奇蹟!只要動動你的金手指,關注下1024譯站這個公衆號,就能第一時間收到我用心創做的技術乾貨!不花一分錢!微信最近也推出了付費閱讀的功能,說明優質內容收費是大趨勢,之後免費的優質內容愈來愈少了!我也建了微信粉絲羣,若是真的發生奇蹟,一定傾情回饋!二維碼就在下面,手機掃起來,一塊兒見證奇蹟!

微信公衆號:1024譯站
相關文章
相關標籤/搜索