这里有一些JavaScript初学者应该知道的技巧和陷阱。 如果你已经是一个专家,那就随意阅读。
你尝试过给一组数字排序吗?
Javascript的sort()
方法默认用来给数字排序
所以[1,2,5,10].sort()
将会输出[1, 10, 2, 5]
.
要正确的对数组进行排序的话,你可以使用[1,2,5,10].sort((a, b) => a — b)
只要你一开始就知道这个坑的话,解决起来就很容易.
new Date()很奇妙
new Date()
可以接受:
- 没有参数就返回当前时间
- 一个参数
x
就返回当前时间1970年1月1日,+ x
毫秒,Unix的人知道为什么 new Date(1,1,1)
返回1901年,2月1日.因为你知道,第一个1意思是1900年后的1年,第二个1是这一年的第二个月(因此二月) —— 二月的正确索引在索引表中为1
,第三个1
显然是这个月的第一天,所以是1
—— 因为有时索引确实从1
开始。- 哦,还有
new Date(2016年,1,1)
不会从2016年追加到1900年。它仅仅表示2016年。
Replace不替代
我觉得这是件好事,因为我不喜欢函数去改变他输入的值,你应该也知道replace
只会替换他第一个匹配:
let s = "bob"
const replaced = s.replace('b', 'l')
replaced === "lob" // first match only
s === "bob" // original string is remained unchanged
如果你想替换所有,你可以使用带有/ g的正则表达式:
"bob".replace(/b/g, 'l') === 'lol' // replace all occurences
当心比较
// 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 ...
? 你知道为什么它却没有输出吗? 你会如何修改它?
我们提出两个可能的解决方案:
使用let
来替换var
。 立马解决。
"在let
和var
之间的差异是作用域,var i
的作用域是最近的函数块,而let
的作用域是最近的封闭块,封闭块可以小于函数块。(如果在任何块之外使用的话,let
和var
它们都是全局的) (source)
其他方法:使用 bind
:
Greeters.push(console.log.bind(null, i))
其实有很多种方法去解决,这是我推荐的2种方法.
聊聊绑定
你认为这个将会输出什么?
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()
理由:greet
没有在正确的上下文运行,同样,是有很多方法可以解决。
我个人比较喜欢
asyncGreet () {
this.someThingAsync()
.then(this.greet.bind(this))
}
这样做可以确保greet
可以被作为上下文的实例调用。
如果你不希望greet
在实例上下文外运行,你还可以在类的constructor
函数中绑定它.
class Foo {
constructor (name) {
this.name = name
this.greet = this.greet.bind(this)
}
}
你还应该知道箭头函数(=>)
可以被用于保留上下文。它也可以这样使用:
asyncGreet () {
this.someThingAsync()
.then(() => {
this.greet()
})
}
本文根据@Aurélien Hervé的《Who said javascript was easy ?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://hackernoon.com/who-said-javascript-easy-f4a1d5b399b8#.47vk2wx3z。
如需转载,烦请注明出处:http://www.w3cplus.com/javascript/who-said-javascript-easy.html