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 相关文章推荐
繁简字转换功能
Jul 19 Javascript
js 操作符实例代码
Oct 24 Javascript
javascript 强制刷新页面的实现代码
Dec 13 Javascript
jquery实现图片翻页效果
Dec 23 Javascript
JavaScript使用push方法添加一个元素到数组末尾用法实例
Apr 06 Javascript
JS for...in 遍历语句用法实例分析
Aug 24 Javascript
bootstrap警告框示例代码分享
May 17 Javascript
PHP7新特性简述
Jun 11 Javascript
把JavaScript代码改成ES6语法不完全指南(分享)
Sep 10 Javascript
JavaScript的setter与getter方法
Nov 29 Javascript
Angular.JS读取数据库数据调用完整实例
Jul 02 Javascript
vue中的过滤器及其时间格式化问题
Apr 09 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同时支持GIF、png、JPEG
2006/10/09 PHP
linux下 C语言对 php 扩展
2008/12/14 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
2011/08/02 PHP
php中禁止单个IP与ip段访问的代码小结
2012/07/04 PHP
php gzip压缩输出的实现方法
2013/04/27 PHP
分享一个php 的异常处理程序
2014/06/22 PHP
codeigniter上传图片不能正确识别图片类型问题解决方法
2014/07/25 PHP
php防止伪造数据从地址栏URL提交的方法
2014/08/24 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
2013/10/22 Javascript
Javasipt:操作radio标签详解
2013/12/30 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
判断访客终端类型集锦
2015/06/05 Javascript
利用vue写todolist单页应用
2016/12/15 Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
2017/03/01 Javascript
nodejs入门教程四:URL相关模块用法分析
2017/04/24 NodeJs
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
2019/03/19 jQuery
小程序的上传文件接口的注意要点解析
2019/09/17 Javascript
vue 对axios get pust put delete封装的实例代码
2020/01/05 Javascript
如何在 ant 的table中实现图片的渲染操作
2020/10/28 Javascript
[02:19]DOTA2女子战队FOX视频专访:希望更多美眉一起加入
2013/10/15 DOTA
Python创建xml文件示例
2017/03/22 Python
python素数筛选法浅析
2018/03/19 Python
python实现在pandas.DataFrame添加一行
2018/04/04 Python
python 遍历列表提取下标和值的实例
2018/12/25 Python
flask项目集成swagger的方法
2020/12/09 Python
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
Html5导航栏吸顶方案原理与对比实现
2020/06/10 HTML / CSS
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
面向对象编程是如何提高软件开发水平的
2014/05/06 面试题
物理专业大学生职业生涯规划书
2014/02/07 职场文书
中学生学雷锋演讲稿
2014/04/26 职场文书
会计试用期自我评价怎么写
2014/09/18 职场文书
2016孝老爱亲模范事迹材料
2016/02/26 职场文书
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
2022/04/24 Vue.js