JavaScript中常见的八个陷阱总结


Posted in Javascript onJune 28, 2017

前言

这里我们针对JavaScript初学者给出一些技巧和列出一些陷阱。如果你已经是一个砖家,也可以读一读。

1. 你是否尝试过对数组元素进行排序?

JavaScript默认使用字典序(alphanumeric)来排序。因此, [1,2,5,10].sort()的结果是[1, 10, 2, 5]。

如果你想正确的排序,应该这样做: [1,2,5,10].sort((a, b) => a - b)

2. new Date() 十分好用

new Date()可以接收:

  • - 不接收任何参数:返回当前时间;
  • - 接收一个参数`x`: 返回1970年1月1日 + `x`毫秒的值。
  • - `new Date(1, 1, 1)`返回1901年2月1号。
  • - 然而...., `new Date(2016, 1, 1)`不会在1900年的基础上加2016,而只是表示2016年。

3. 替换函数没有真的替换?

let s = "bob"
const replaced = s.replace('b', 'l')
replaced === "lob" // 只会替换掉第一个b
s === "bob" // 并且s的值不会变

如果你想把所有的b都替换掉,要使用正则:

"bob".replace(/b/g, 'l') === 'lol'

4. 谨慎对待比较运算

// 这些可以
'abc' === 'abc' // true
1 === 1 // true
// 然而这些不行
[1,2,3] === [1,2,3] // false
{a: 1} === {a: 1} // false
{} === {} // false

因为[1,2,3]和[1,2,3]是两个不同的数组,只是它们的元素碰巧相同。因此,不能简单的通过`===`来判断。

5. 数组不是基础类型

typeof {} === 'object' // true
typeof 'a' === 'string' // true
typeof 1 === number // true
// 但是....
typeof [] === 'object' // true

如果要判断一个变量`var`是否是数组,你需要使用`Array.isArray(var)`

6. 闭包

这是一个经典的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,...,然而实际上却不会。知道如何Debug嘛?

有两种方法:

  • - 使用`let`而不是`var`。 (备注:可以参考这篇文章 https://3water.com/article/117343.htm)
  • - 使用`bind`函数。(备注:可以参考这篇文章 https://3water.com/article/115323.htm)
Greeters.push(console.log.bind(null, i))

当然,还有很多解法。这两种是我最喜欢的!

7. 关于bind

下面这段代码会输出什么结果?

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

因为第16行的`geet`没有在正确的环境下执行。当然,也有很多方法解决这个BUG!

- 我喜欢使用`bind`函数来解决问题:

asyncGreet () {
 this.someThingAsync()
 .then(this.greet.bind(this))
}

这样会确保`greet`会被Foo的实例调用,而不是局部的函数的`this`。

- 如果你想要`greet`永远不会绑定到错误的作用域,你可以在构造函数里面使用`bind`来绑定。

class Foo {
 constructor (name) {
 this.name = name
 this.greet = this.greet.bind(this)
 }
}

- 你也可以使用箭头函数(=>)来防止作用域被修改。 (备注:可以参考这篇文章 https://3water.com/article/115318.htm)  

asyncGreet () {
 this.someThingAsync()
 .then(() => {
 this.greet()
 })
}

8. Math.min()比Math.max()大

Math.min() < Math.max() // false

因为Math.min() 返回 Infinity, 而 Math.max()返回 -Infinity。

原文: Who said javascript was easy ?

译者: Fundebug

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
自己整理的一个javascript日期处理函数
Oct 16 Javascript
js自定义事件代码说明
Jan 31 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
Aug 12 Javascript
JavaScript中判断整数的多种方法总结
Nov 08 Javascript
js自定义回调函数
Dec 13 Javascript
Bootstrap表单布局
Jul 19 Javascript
JavaScript的六种继承方式(推荐)
Jun 26 Javascript
json对象及数组键值的深度大小写转换问题详解
Mar 30 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
Apr 25 Javascript
js实现简单的随机点名器
Sep 17 Javascript
一行JavaScript代码如何实现瀑布流布局
Dec 11 Javascript
vue导入.md文件的步骤(markdown转HTML)
Dec 31 Vue.js
通过构造函数实例化对象的方法
Jun 28 #Javascript
JS之if语句对接事件动作逻辑(详解)
Jun 28 #Javascript
CSS3+JavaScript实现翻页幻灯片效果
Jun 28 #Javascript
Node.js 8 中的重要新特性
Jun 28 #Javascript
Angular排序实例详解
Jun 28 #Javascript
基于JS对象创建常用方式及原理分析
Jun 28 #Javascript
Node.js实现文件上传的示例
Jun 28 #Javascript
You might like
用 PHP5 轻松解析 XML
2006/12/04 PHP
比较详细PHP生成静态页面教程
2012/01/10 PHP
php笔记之:初探PHPcms模块开发介绍
2013/04/26 PHP
php生成扇形比例图实例
2013/11/06 PHP
PHP的password_hash()使用实例
2014/03/17 PHP
原创javascript小游戏实现代码
2010/08/19 Javascript
js的表单操作 简单计算器
2011/12/29 Javascript
js里怎么取select标签里的值并修改
2012/12/10 Javascript
js实现的标题栏新消息闪烁提示效果
2014/06/06 Javascript
Javascript判断文件是否存在(客户端/服务器端)
2014/09/16 Javascript
Javascript基础教程之数据类型转换
2015/01/18 Javascript
在for循环中length值是否需要缓存
2015/07/27 Javascript
学习JavaScript鼠标响应事件
2015/12/25 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
2016/05/16 Javascript
javascript实现的全国省市县无刷新多级关联菜单效果代码
2016/08/01 Javascript
利用JS实现scroll自定义滚动效果详解
2017/10/17 Javascript
解决vue单页面应用进入页面加载所有 js 的问题
2020/08/12 Javascript
[44:47]Ti4 循环赛第三日 iG vs NaVi
2014/07/12 DOTA
基于tensorflow加载部分层的方法
2018/07/26 Python
python递归全排列实现方法
2018/08/18 Python
win10下python3.5.2和tensorflow安装环境搭建教程
2018/09/19 Python
Python函数中参数是传递值还是引用详解
2019/07/02 Python
python给list排序的简单方法
2020/12/10 Python
HTML5 虚拟键盘出现挡住输入框的解决办法
2017/02/14 HTML / CSS
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
历史专业个人求职信分享
2013/12/20 职场文书
本科生导师推荐信范文
2014/05/18 职场文书
售后客服工作职责
2014/06/16 职场文书
电子商务专业应届毕业生求职信
2014/06/21 职场文书
2015年护士医德医风自我评价
2015/03/03 职场文书
公司出纳岗位职责
2015/03/31 职场文书
采购员岗位职责范本
2015/04/07 职场文书
舞蹈社团活动总结
2015/05/07 职场文书
党员电教片《信仰》心得体会
2016/01/15 职场文书
文书工作总结(范文)
2019/07/11 职场文书
导游词之鲁迅祖居
2019/10/17 职场文书