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 相关文章推荐
获取焦点时,利用js定时器设定时间执行动作
Apr 02 Javascript
关于jquery动态增减控件的一些想法和小插件
Aug 01 Javascript
jQuery 1.9.1源码分析系列(十五)之动画处理
Dec 03 Javascript
Javascript类型转换的规则实例解析
Feb 23 Javascript
vue.js入门教程之基础语法小结
Sep 01 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
Sep 04 Javascript
jQuery实现移动端手机商城购物车功能
Sep 24 Javascript
Javascript的this用法
Jan 16 Javascript
js 调用百度分享功能
Feb 27 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
Dec 29 Javascript
Node.js 使用AngularJS的方法示例
May 11 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
May 25 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
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
跟我学Laravel之快速入门
2014/10/15 PHP
php使用session二维数组实例
2014/11/06 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
很可爱的输入框
2008/08/03 Javascript
Jquery异步请求数据实例代码
2011/12/28 Javascript
Javascript页面添加到收藏夹的简单方法
2013/08/07 Javascript
jquery+css3实现会动的小圆圈效果
2016/01/27 Javascript
Node.js+Express配置入门教程详解
2016/05/19 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
2017/05/11 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
基于 Bootstrap Datetimepicker 联动
2017/08/03 Javascript
JS监控关闭浏览器操作的实例详解
2017/09/12 Javascript
vue中axios处理http发送请求的示例(Post和get)
2017/10/13 Javascript
详解Vue中CSS样式穿透问题
2019/09/12 Javascript
Vue-router编程式导航的两种实现代码
2021/03/04 Vue.js
[44:21]Ti4 循环赛第四日 附加赛NEWBEE vs LGD
2014/07/13 DOTA
python类定义的讲解
2013/11/01 Python
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
Django Highcharts制作图表
2016/08/27 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
Django学习教程之静态文件的调用详解
2018/05/08 Python
python处理数据,存进hive表的方法
2018/07/04 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
HTML5实现移动端点击翻牌功能
2020/10/23 HTML / CSS
英国轻奢珠宝品牌:Astley Clarke
2016/12/18 全球购物
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
写好自荐信的几个要点
2013/12/26 职场文书
列车长先进事迹材料
2014/01/25 职场文书
项目建议书格式
2014/03/12 职场文书
承诺书的格式范文
2014/03/28 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
教师党员群众路线教育实践活动心得体会
2014/11/04 职场文书
发布会邀请函
2015/01/31 职场文书
大学军训决心书
2015/02/05 职场文书
会议新闻稿
2015/07/17 职场文书