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 相关文章推荐
Ruffy javascript 学习笔记
Nov 30 Javascript
JQuery 操作Javascript对象和数组的工具函数小结
Jan 22 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
Dec 16 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
Mar 02 Javascript
jQuery根据name属性进行查找的用法分析
Jun 23 Javascript
一个超简单的jQuery回调函数例子(分享)
Aug 08 Javascript
JavaScript实现简单的树形菜单效果
Jun 23 Javascript
vue axios用法教程详解
Jul 23 Javascript
js实现省市级联效果分享
Aug 10 Javascript
vue router带参数页面刷新或回退参数消失的解决方法
Feb 27 Javascript
vue $set 给数据赋值的实例
Nov 09 Javascript
JS代码简洁方式之函数方法详解
Jul 28 Javascript
通过构造函数实例化对象的方法
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
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
面向对象的javascript(笔记)
2009/10/06 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
AngularJS入门示例之Hello World详解
2017/01/04 Javascript
jquery的 filter()方法使用教程
2018/03/22 jQuery
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
微信小程序添加插屏广告并设置显示频率(一天一次)
2019/12/06 Javascript
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
[01:06]DOTA2小知识课堂 Ep.02 吹风竟可解梦境缠绕
2019/12/05 DOTA
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
python中pygame模块用法实例
2014/10/09 Python
Python格式化css文件的方法
2015/03/10 Python
Python爬虫之模拟知乎登录的方法教程
2017/05/25 Python
python urllib爬取百度云连接的实例代码
2017/06/19 Python
Python实现PS滤镜中马赛克效果示例
2018/01/20 Python
用 Python 连接 MySQL 的几种方式详解
2018/04/04 Python
对django中render()与render_to_response()的区别详解
2018/10/16 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
Python 20行简单实现有道在线翻译的详解
2019/05/15 Python
Win10+GPU版Pytorch1.1安装的安装步骤
2019/09/27 Python
Django后端发送小程序微信模板消息示例(服务通知)
2019/12/17 Python
Django-xadmin+rule对象级权限的实现方式
2020/03/30 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
PyQt5结合matplotlib绘图的实现示例
2020/09/15 Python
谈谈对css属性box-sizing的了解
2017/01/04 HTML / CSS
浅谈html5 响应式布局
2014/12/24 HTML / CSS
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
MVMT手表官方网站:时尚又实惠的高品质手表
2016/12/04 全球购物
国际贸易专业推荐信
2013/11/15 职场文书
资金主管岗位职责范本
2014/03/04 职场文书
2014年班长个人工作总结
2014/11/14 职场文书
HR必备:销售经理聘用合同范本
2019/08/21 职场文书
创业计划书之花店
2019/09/20 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书
62句有关感恩节文案(推荐收藏)
2019/11/28 职场文书
mysql幻读详解实例以及解决办法
2022/06/16 MySQL