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 相关文章推荐
一个tab标签切换效果代码
Mar 27 Javascript
javascript 限制输入脚本大全
Nov 03 Javascript
JQUERY 实现窗口滚动搜索框停靠效果(类似滚动停靠)
Mar 27 Javascript
js的onload事件及初始化按钮事件示例代码
Sep 25 Javascript
基于javascript实现的搜索时自动提示功能
Dec 26 Javascript
jquery mobile开发常见问题分析
Jan 21 Javascript
DeviceOne 让你一见钟情的App快速开发平台
Feb 17 Javascript
jQuery内容筛选选择器实例代码
Feb 06 Javascript
Vue.js项目部署到服务器的详细步骤
Jul 17 Javascript
解析Angular 2+ 样式绑定方式
Jan 15 Javascript
Vue.js子组件向父组件通信的方法实例代码详解
Dec 10 Javascript
微信小程序动态添加和删除组件的现实
Feb 28 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 JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
PHP 获取 ping 时间的实现方法
2017/09/29 PHP
laravel接管Dingo-api和默认的错误处理方式
2019/10/25 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
js中将具有数字属性名的对象转换为数组
2011/03/06 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
2013/12/24 Javascript
jQuery插件formValidator自定义函数扩展功能实例详解
2015/11/25 Javascript
js简单时间比较的方法
2016/08/02 Javascript
浅谈JavaScript事件绑定的常用方法及其优缺点分析
2016/11/01 Javascript
Html5 js实现手风琴效果
2020/04/17 Javascript
Vue2.0 组件传值通讯的示例代码
2017/08/01 Javascript
javascript实现文件拖拽事件
2018/03/29 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
2018/11/05 Javascript
JavaScript使用Math.random()生成简单的验证码
2019/01/21 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
vue-video-player 解决微信自动全屏播放问题(横竖屏导致样式错乱问题)
2020/02/25 Javascript
[05:29]2014DOTA2国际邀请赛 赛后专访:LGDNewbee顺利过关
2014/07/13 DOTA
Python中的赋值、浅拷贝、深拷贝介绍
2015/03/09 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
2018/04/19 Python
Django Admin实现三级联动的示例代码(省市区)
2018/06/22 Python
python微信好友数据分析详解
2018/11/19 Python
python程序运行进程、使用时间、剩余时间显示功能的实现代码
2019/07/11 Python
python之pexpect实现自动交互的例子
2019/07/25 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
2020/05/15 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
法国房车租赁网站:Yescapa
2019/08/26 全球购物
时尚孕妇装:HATCH Collection
2019/09/24 全球购物
省级四好少年事迹材料
2014/01/25 职场文书
工程建设实施方案
2014/03/14 职场文书
《北京的春节》教学反思
2014/04/07 职场文书
临床医学生职业规划书范文
2014/10/25 职场文书
护士个人年度总结范文
2015/02/13 职场文书
2015年计划生育责任书
2015/05/08 职场文书
外出培训学习心得体会
2016/01/18 职场文书
修辞手法有哪些?
2019/08/29 职场文书