转载

谁说JavaScript容易?

这里有一些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 。 立马解决。

"在 letvar 之间的差异是作用域, var i 的作用域是最近的函数块,而 let 的作用域是最近的封闭块,封闭块可以小于函数块。(如果在任何块之外使用的话, letvar 它们都是全局的) ( 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 。

Bibi

前端程序媛,追求有趣的技术,学习有趣的事物,我享受把灵感通过代码具象化的过程,认为前端开发更像是一门优美的艺术。I'm a "Creator" in my code.

原文  http://www.w3cplus.com/javascript/who-said-javascript-easy.html
正文到此结束
Loading...