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 相关文章推荐
关于恒等于(===)和非恒等于(!==)
Aug 20 Javascript
jquery中常用的SET和GET
Jan 13 Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
Oct 29 Javascript
JQuery动画与特效实例分析
Feb 02 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
Oct 12 Javascript
基于jQuery Tipso插件实现消息提示框特效
Mar 16 Javascript
JS解决iframe之间通信和自适应高度的问题
Aug 24 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
Jul 19 jQuery
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
Jul 30 Javascript
jQuery阻止事件冒泡实例分析
Jul 03 jQuery
vue项目前端知识点整理【收藏】
May 13 Javascript
vue项目中自定义video视频控制条的实现代码
Apr 26 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
新浪新闻小偷
2006/10/09 PHP
实现“上一页”和“下一页按钮
2006/10/09 PHP
理解PHP5中static和const关键字的区别
2007/03/19 PHP
使用php统计字符串中中英文字符的个数
2013/06/23 PHP
10 个经典PHP函数
2013/10/17 PHP
PHP分页类集锦
2014/11/18 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
php设计模式之单例模式实例分析
2015/02/25 PHP
PHP扩展程序实现守护进程
2015/04/16 PHP
在Laravel 中实现是否关注的示例
2019/10/22 PHP
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
MultiSelect左右选择控件的设计与实现介绍
2013/06/08 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
2015/12/31 Javascript
JQuery ztree 异步加载实例讲解
2016/02/25 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
JavaScript继承定义与用法实践分析
2018/05/28 Javascript
vue 实现在函数中触发路由跳转的示例
2018/09/01 Javascript
JavaScript作用域链实例详解
2019/01/21 Javascript
解决layer.open弹出框不能获取input框的值为空的问题
2019/09/10 Javascript
基于js实现判断浏览器类型代码实例
2020/07/17 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
[30:37]【全国守擂赛】第三周擂主赛 Dark Knight vs. Leopard Gaming
2020/05/04 DOTA
python 数字类型和字符串类型的相互转换实例
2018/07/17 Python
win10下tensorflow和matplotlib安装教程
2018/09/19 Python
Roots加拿大官网:加拿大休闲服饰品牌
2016/10/24 全球购物
英国领先的维生素和营养补充剂直接供应商:Healthspan
2019/04/22 全球购物
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
后勤副校长自我鉴定
2013/10/13 职场文书
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
房产公证书范本
2014/04/10 职场文书
学校政风行风评议心得体会
2014/10/21 职场文书
优秀班集体事迹材料
2014/12/25 职场文书
病危通知书样本
2015/04/17 职场文书
python 使用tkinter与messagebox写界面和弹窗
2022/03/20 Python