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 相关文章推荐
JavaScript 对象链式操作测试代码
Apr 25 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
Mar 28 Javascript
js异步加载的三种解决方案
Mar 04 Javascript
js取消单选按钮选中示例代码
Nov 14 Javascript
全面解析Bootstrap排版使用方法(文字样式)
Nov 30 Javascript
基于JS实现横线提示输入验证码随验证码输入消失(js验证码的实现)
Oct 27 Javascript
javascript编程实现栈的方法详解【经典数据结构】
Apr 11 Javascript
vue数据双向绑定的注意点
Jun 23 Javascript
浅谈JavaScript find 方法不支持IE的问题
Sep 28 Javascript
本地搭建微信小程序服务器的实现方法
Oct 27 Javascript
Vue进度条progressbar组件功能
Apr 17 Javascript
vue devtools的安装与使用教程
Aug 08 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获取网络上文件
2006/10/09 PHP
怎样在PHP中通过ADO调用Asscess数据库和COM程序
2006/10/09 PHP
PHP读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP连接局域网MYSQL数据库的简单实例
2013/08/26 PHP
phpMyAdmin安装并配置允许空密码登录
2015/07/04 PHP
innerHTML,outerHTML,innerTEXT三者之间的区别
2007/01/28 Javascript
幻灯片带网页设计中的20个奇妙应用示例小结
2012/05/27 Javascript
js改变文章字体大小的实例代码
2013/11/27 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
2015/06/10 Javascript
使用jQuery监听DOM元素大小变化
2016/02/24 Javascript
JavaScript_ECMA5数组新特性详解
2016/06/12 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
jQuery电话号码验证实例
2017/01/05 Javascript
使用Xcache缓存器加速PHP网站的配置方法
2017/04/22 Javascript
基于jquery日历价格、库存等设置插件
2020/07/05 jQuery
在vue项目中,将juery设置为全局变量的方法
2018/09/25 Javascript
详解Vue中watch的详细用法
2018/11/28 Javascript
vue中用 async/await 来处理异步操作
2020/07/18 Javascript
JavaScript canvas实现雨滴特效
2021/01/10 Javascript
[02:19]DOTA选手解说齐贺岁
2018/02/11 DOTA
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
Python编程入门的一些基本知识
2015/05/13 Python
用vue.js组件模拟v-model指令实例方法
2019/07/05 Python
Django model update的多种用法介绍
2020/03/28 Python
使用Python实现图像标记点的坐标输出功能
2019/08/14 Python
python中对二维列表中一维列表的调用方法
2020/06/07 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
HTML5标签嵌套规则详解【必看】
2016/04/26 HTML / CSS
HTML5中外部浏览器唤起微信分享
2020/01/02 HTML / CSS
澳大利亚婴儿礼品公司:The Baby Gift Company
2018/11/04 全球购物
Lookfantastic澳大利亚官网:英国知名美妆购物网站
2021/01/07 全球购物
办公室文员工作自我评价
2013/12/01 职场文书
素质拓展感言
2014/01/29 职场文书
城管综合整治方案
2014/05/01 职场文书
曾国藩励志经典名言37句,蕴含哲理
2019/10/14 职场文书