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据option的value值快速设定初始的selected选项
Aug 13 Javascript
JavaScript 组件之旅(一)分析和设计
Oct 28 Javascript
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
Oct 23 Javascript
vue.js评论发布信息可插入QQ表情功能
Aug 08 Javascript
详解extract-text-webpack-plugin 的使用及安装
Jun 12 Javascript
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
Jan 18 Javascript
详解实现一个通用的“划词高亮”在线笔记功能
Apr 23 Javascript
JS实现的贪吃蛇游戏案例详解
May 01 Javascript
react-native滑动吸顶效果的实现过程
Jun 03 Javascript
JavaScript创建、读取和删除cookie
Sep 03 Javascript
p5.js临摹动态图形实现方法详解
Oct 23 Javascript
Element MessageBox弹框的具体使用
Jul 27 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 一个比较完善的简单文件上传
2010/03/25 PHP
PHP往XML中添加节点的方法
2015/03/12 PHP
基于PHP实现数据分页显示功能
2016/05/26 PHP
ThinkPHP实现分页功能
2017/04/28 PHP
Ubuntu 16.04中Laravel5.4升级到5.6的步骤
2018/12/07 PHP
PHP反射基础知识回顾
2020/09/10 PHP
Google韩国首页图标动画效果
2007/08/26 Javascript
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
超级24小时弹窗代码 24小时退出弹窗代码 100%弹窗代码(IE only)
2010/06/11 Javascript
基于Jquery 解决Ajax请求的页面 浏览器后退前进功能,页面刷新功能实效问题
2010/12/11 Javascript
映彩衣的js随笔(js图片切换效果)
2011/07/31 Javascript
NodeJS的模块写法入门(实例代码)
2012/03/07 NodeJs
JavaScript调试技巧之console.log()详解
2014/03/19 Javascript
jquery性能优化高级技巧
2015/08/24 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
jQuery源码分析之sizzle选择器详解
2017/02/13 Javascript
ionic中的$ionicPlatform.ready事件中的通用设置
2017/06/11 Javascript
jQuery中内容过滤器简单用法示例
2018/03/31 jQuery
JS与jQuery判断文本框还剩多少字符可以输入的方法
2018/09/01 jQuery
解决vue点击控制单个样式的问题
2018/09/05 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
在Vue项目中引入JQuery-ui插件的讲解
2019/01/27 jQuery
基于elementUI使用v-model实现经纬度输入的vue组件
2019/05/12 Javascript
Bootstrap实现省市区三级联动(亲测可用)
2019/07/26 Javascript
JavaScript碰撞检测原理及其实现代码
2020/03/12 Javascript
Taro小程序自定义顶部导航栏功能的实现
2020/12/17 Javascript
[02:42]DOTA2英雄基础教程 杰奇洛
2013/12/23 DOTA
[43:51]2014 DOTA2国际邀请赛中国区预选赛 Dream Times VS TongFu
2014/05/22 DOTA
Python中字典和JSON互转操作实例
2015/01/19 Python
python生成式的send()方法(详解)
2017/05/08 Python
python利用正则表达式搜索单词示例代码
2017/09/24 Python
视图的作用
2014/12/19 面试题
关于热爱祖国的演讲稿
2014/05/04 职场文书
小学语文教学随笔
2015/08/14 职场文书
PHP解决高并发问题
2021/04/01 PHP
Nginx流量拷贝ngx_http_mirror_module模块使用方法详解
2022/04/07 Servers