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 removeChild 障眼法 可能出现的错误
Oct 06 Javascript
jQuery学习笔记 更改jQuery对象
Sep 19 Javascript
Extjs grid panel自带滚动条失效的解决方法
Sep 11 Javascript
node.js缺少mysql模块运行报错的解决方法
Nov 13 Javascript
微信小程序  wx.request合法域名配置详解
Nov 23 Javascript
jQuery实现简易的输入框字数计数功能示例
Jan 16 Javascript
jquery事件与绑定事件
Mar 16 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
Jul 04 Javascript
vue-cli3 配置开发与测试环境详解
May 17 Javascript
jquery插件开发模式实例详解
Jul 20 jQuery
JS document对象简单用法完整示例
Jan 14 Javascript
js实现点击上传图片并设为模糊背景
Aug 02 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 nl2br()格式化输出的详解
2013/06/05 PHP
php遍历文件夹下的所有文件和子文件夹示例
2014/03/20 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
PHP判断手机是IOS还是Android
2015/12/09 PHP
Smarty环境配置与使用入门教程
2016/05/11 PHP
PHP实现导出excel数据的类库用法示例
2016/10/15 PHP
thinkphp分页集成实例
2017/07/24 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】
2020/05/26 PHP
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
javascript setinterval 的正确语法如何书写
2014/06/17 Javascript
Javascript学习笔记之 对象篇(一) : 对象的使用和属性
2014/06/24 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
JavaScript里 ==与===区别详解
2016/08/16 Javascript
js获取一组日期中最近连续的天数
2017/05/25 Javascript
利用node.js实现自动生成前端项目组件的方法详解
2017/07/12 Javascript
vue中如何创建多个ueditor实例教程
2017/11/14 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
微信小程序实现渐入渐出动画效果
2019/06/13 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
antd配置config-overrides.js文件的操作
2020/10/31 Javascript
详解ES6 扩展运算符的使用与注意事项
2020/11/12 Javascript
[01:01:24]LGD vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
浅谈django中的认证与登录
2016/10/31 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
2017/06/20 Python
python+VTK环境搭建及第一个简单程序代码
2017/12/13 Python
水果花束:Fruit Bouquets
2017/12/20 全球购物
美国床垫连锁店:Mattress Firm
2021/02/13 全球购物
说出数据连接池的工作机制是什么?
2013/04/19 面试题
什么造成了Java里面的异常
2016/04/24 面试题
韩语专业本科生求职信
2013/10/01 职场文书
2015年机关党委工作总结
2015/05/23 职场文书
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
Java如何实现通过键盘输入一个数组
2022/02/15 Java/Android
MySQL下载安装配置详细教程 附下载资源
2022/09/23 MySQL