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 相关文章推荐
setInterval 和 setTimeout会产生内存溢出
Feb 15 Javascript
top.location.href 没有权限 解决方法
Aug 05 Javascript
使用JS 清空File控件的路径值
Jul 08 Javascript
js 编码转换 gb2312 和 utf8 互转的2种方法
Aug 07 Javascript
导航跟随滚动条置顶移动示例代码
Sep 11 Javascript
css结合js制作下拉菜单示例代码
Feb 27 Javascript
jquery bind(click)传参让列表中每行绑定一个事件
Aug 06 Javascript
js实现的奥运倒计时时钟效果代码
Dec 09 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
Feb 19 Javascript
详解webpack3编译兼容IE8的正确姿势
Dec 21 Javascript
百度小程序之间的页面通信过程详解
Jul 18 Javascript
React更新渲染原理深入分析
Dec 24 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
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
2007/09/30 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
PHP7生产环境队列Beanstalkd用法详解
2020/05/19 PHP
JavaScript CSS修改学习第二章 样式
2010/02/19 Javascript
apycom出品的jQuery精美菜单破解方法
2011/02/18 Javascript
探讨js中的双感叹号判断
2013/11/11 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
js实现卡片式项目管理界面UI设计效果
2015/12/08 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
使用JavaScript获取Request中参数的值方法
2016/09/27 Javascript
Javascript 正则表达式校验数字的简单实例
2016/11/02 Javascript
微信小程序 动态绑定数据及动态事件处理
2017/03/14 Javascript
基于JavaScript实现滑动门效果
2017/03/16 Javascript
JS仿Base.js实现的继承示例
2017/04/07 Javascript
JSON对象转化为字符串详解
2017/08/11 Javascript
iview同时验证多个表单问题总结
2018/09/29 Javascript
jquery的$().each和$.each的区别
2019/01/18 jQuery
JS使用for in有序获取对象数据
2020/05/19 Javascript
js实现筛选功能
2020/11/24 Javascript
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
2021/03/01 Vue.js
python单元测试unittest实例详解
2015/05/11 Python
python 寻找优化使成本函数最小的最优解的方法
2017/12/28 Python
Python高级用法总结
2018/05/26 Python
python求最大连续子数组的和
2018/07/07 Python
在python下读取并展示raw格式的图片实例
2019/01/24 Python
Python xlwt模块使用代码实例
2020/06/10 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
大学生水文观测实习自我鉴定
2013/09/29 职场文书
留学自荐信
2013/10/10 职场文书
技术人员面试提纲
2013/11/28 职场文书
房屋继承公证书
2014/04/10 职场文书
工作目标责任书
2014/07/23 职场文书
地震捐款倡议书
2014/08/29 职场文书
歌颂党的演讲稿
2014/09/10 职场文书
上课说话检讨书500字
2014/11/01 职场文书
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android