本文做者:Aurélien Hervé
編譯:鬍子大哈 javascript翻譯原文:http://huziketang.com/blog/posts/detail?postId=58e06b98a58c240ae35bb8dd
英文鏈接:Who said javascript was easy ?java
轉載請註明出處,保留原文連接以及做者信息react
本文介紹了 JavaScript 初學者應該知道的一些技巧和陷阱。若是你是老司機,就當作回顧了,哪裏有寫的很差的地方歡迎指出。面試
JavaScript 中的 sort()
默認是按字母排序的。因此好比你這樣 [1,2,5,10].sort()
,會輸出 [1,10,2,5]
。數組
正確的排序可使用 [1,2,5,10].sort((a, b) => a — b)
。閉包
是否是很簡單,這個知識點是告訴你第一種方式排序是有問題的。async
new Date()
能夠接收:函數
無參數:返回當前時間;post
1 個參數 x:返回 1970 年 1 月 1 日 + x 毫秒時間。Unix 的小夥伴知道爲何是這樣;學習
new Date(1,1,1) 返回 1901 年 2 月 1 日:第一個 「1」 表明 1900 年之後的第 1 年;第二個 「1」 表明這一年的第 2 個月(並非像你想象的那樣從 1 月開始);第三個 「1」 表明這個月的第 1 天(這個確實是如你想象的那樣從 1 開始)。
new Date(2017,1,1) :這並非表示 1900 + 2017了,它就是表示 2017 年 1 月 1 日。
對於原始串不被替換掉,我是雙手贊同的,我不喜歡一個函數的輸入老是在變化。另外你應該知道 replace
只會替換第一個匹配上的字符。
let s = "bob" const replaced = s.replace('b', 'l') replaced === "lob" // 只替換第一個匹配上的 s === "bob" // 原始串始終沒變
若是你想替換全部的,那就是用正則符 /g
:
"bob".replace(/b/g, 'l') === 'lol' // 替換全部串
// These are ok 'abc' === 'abc' // true 1 === 1 // true // These are not [1,2,3] === [1,2,3] // false {a: 1} === {a: 1} // false {} === {} // false
緣由:[1,2,3] 和 [1,2,3] 是兩個數組,它們只是恰巧值相等罷了,他們的引用是不一樣的,因此不能用簡單的 ===
來比較。
typeof {} === 'object' // true typeof 'a' === 'string' // true typeof 1 === number // true // But.... typeof [] === 'object' // true
想知道你的變量是否是數組,仍然可使用 Array.isArray(myVar)
。
這是很出名的一道 JavaScript 面試題:
const Greeters = [] for (var i = 0 ; i < 10 ; i++) { Greeters.push(function () { return console.log(i) }) } Greeters[0]() // 10 Greeters[1]() // 10 Greeters[2]() // 10
你預期的是輸出:0,1,2...嗎?你知道這是爲何嗎?你知道怎麼 fix 嗎?
我來提兩種可能的解決方案來解決這個問題:
第一種:使用 let
,不用 var
。Duang!解決了~
let
和var
的區別是做用域。var
的做用域是最近的函數塊。而let
的做用域是最近的封閉塊。若是兩個都是在塊外的,那兩個都是全局的。最近的封閉塊,要比最近的函數塊範圍小。這裏是源碼。
第二種:使用 bind
。
Greeters.push(console.log.bind(null, i))
還有不少方法能夠解決這一問題,這裏列出了我我的的兩種最優選擇。
你以爲下面的代碼會輸出什麼?
class Foo { constructor (name) { this.name = name } greet () { console.log('hello, this is ', this.name) } someThingAsync () { return Promise.resolve() } asyncGreet () { this.someThingAsync() .then(this.greet) } } new Foo('dog').asyncGreet()
給你點提示,你認爲是否會拋出異常呢?Cannot read property 'name' of undefined
。
緣由:greet
沒有在恰當的上下文中執行。依舊,有不少種方法解決這個問題。
第一種:我我的比較喜歡以下解決方法。
asyncGreet () { this.someThingAsync() .then(this.greet.bind(this)) }
這種方式能夠保證 greet
是在類已經實例化之後被調用。
第二種:若是你想確保 greet
始終能夠正確調用,能夠綁定到構造函數中。
class Foo { constructor (name) { this.name = name this.greet = this.greet.bind(this) } }
第三種:你還應該知道箭頭函數(=>
)能夠保護上下文,也能夠解決這個問題。
asyncGreet () { this.someThingAsync() .then(() => { this.greet() }) }
雖然我以爲最後一種解決方案這個例子中很不優雅……
恭喜!到如今你知道了 JavaScript 中的一些坑,和一點技巧。JavaScript 中還有不少知識等待着你去學習,不過起碼在這幾個問題上,你不會再犯錯誤了。Cheers! o/
若是你認爲文章中還須要注意什麼,或者添加什麼,請讓我知道。
我最近正在寫一本《React.js 小書》,對 React.js 感興趣的童鞋,歡迎指點。