当前位置: 首页 > 编程日记 > 正文

JS中8个常见的陷阱

译者按: 漫漫编程路,总有一些坑让你泪流满面。

  • 原文: Who said javascript was easy ?

  • 译者: Fundebug

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习

这里我们针对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" s === "bob" 

如果你想把所有的b都替换掉,要使用正则:

  "bob".replace(/b/g, 'l') === 'lol'

4. 谨慎对待比较运算

  // 这些可以'abc' === 'abc' // true1 === 1         // true// 然而这些不行[1,2,3] === [1,2,3] // false{a: 1} === {a: 1}   // false{} === {}           // false

因为[1,2,3]和[1,2,3]是两个不同的数组,只是它们的元素碰巧相同。因此,不能简单的通过===来判断。

5. 数组不是基础类型

  typeof {} === 'object' typeof 'a' === 'string' typeof 1 === number // 但是....typeof [] === 'object'  

如果要判断一个变量var是否是数组,你需要使用Array.isArray(var)

6. 闭包

这是一个经典的JavaScript面试题:

  const Greeters = []for (var i = 0 ; i < 10 ; i++) {Greeters.push(function () { return console.log(i) })}Greeters[0]() // 10Greeters[1]() // 10Greeters[2]() // 10

虽然期望输出0,1,2,...,然而实际上却不会。知道如何Debug嘛?
有两种方法:

  • 使用let而不是var。备注:可以参考Fundebug的另一篇博客[ ES6之"let"能替代"var"吗?](https://blog.fundebug.com/2017/05/04/ hy-you-should-not-use-var/)
  • 使用bind函数。备注:可以参考Fundebug的另一篇博客[ JavaScript初学者必看“this”](https://blog.fundebug.com/2017/05/17/ avascript-this-for-beginners/)
    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 = namethis.greet = this.greet.bind(this)}
    }
  • 你也可以使用箭头函数(=>)来防止作用域被修改。备注:可以参考Fundebug的另一篇博客[ JavaScript初学者必看“箭头函数”](https://blog.fundebug.com/2017/05/25/ rrow-function-for-beginner/)。
    asyncGreet () {this.someThingAsync().then(() => {this.greet()})
    }

8. Math.min()比Math.max()大

  Math.min() < Math.max() 

因为Math.min() 返回 Infinity, 而 Math.max()返回 -Infinity。

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

JS中8个常见的陷阱

版权声明

转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/06/28/who-said-js-was-easy/

转载于:https://blog.51cto.com/13957060/2317508

相关文章:

支持支付宝(Alipay)付款的三个美国主机商

这段时间买国外主机的筒子们越来越多&#xff0c;而付款就是首先摆在大家眼前的一道障碍&#xff0c;大部分美国主机商只能通过信用卡购买&#xff0c;付款不方便。因为这个原因&#xff0c;很多人的美国主机都是从国内的公司或者个人买的&#xff0c;无法享受美国主机的优质服…

(C++)string 的两种输入方式和输出方式

注&#xff1a;头文件如下 #include<string> #include<cstdio> #include<iostream>using namespace std; 注&#xff1a;第一种输入方式遇到回车停止读入&#xff0c;第二种输入方式遇到空格停止读入。 两种读入方式也都可以用来读字符数组。 int main()…

ob_get_contents();basename;file_get_contents用法

ob_get_contents(); ob_end_clean(); ob_start()使用ob_start()把输出那同输出到缓冲区&#xff0c;而不是到浏览器。然后用ob_get_contents得到缓冲区的数据。 ob_start()在服务器打开一个缓冲区来保存所有的输出。所以在任何时候使用echo &#xff0c;输出都将被加入缓冲区中…

零基础学汇编 --小甲鱼

来自http://www.51xue8.com/diannao/wangluobiancheng/2013-11-06/6584.html#fillback0100307b617b7b7b303232303266313839397b677b7b240000&anchortestanchor转载于:https://www.cnblogs.com/I-L-o-v-e-z-h-o-u/p/4235340.html

数据标准化_1

from sklearn.datasets import load_irisirisload_iris()#Z-score 数据标准化from sklearn.preprocessing import StandardScalerdata_standardStandardScaler().fit_transform(iris.data)# print(data_standard,data_standard)#Min-Maxfrom sklearn.preprocessing import MinM…

PAT(甲级)2021年春季考试 7-1 Arithmetic Progression of Primes

思路&#xff1a;用筛除法打素数表(与之相对的是枚举加逐个判断)是降低时间复杂度的第一个点&#xff0c;第二个点是运用上数学技巧&#xff0c;给定了等差数列的范围(2-MAX)&#xff0c;给定了个数&#xff0c;那么最大的等差是可以求出的。循环的第一层从最大等差开始&#x…

hadoop中HBase子项目入门讲解

HBase 是Hadoop的一个子项目,HBase采用了Google BigTable的稀疏的,面向列的数据库实现方式的理论,建立在hadoop的hdfs上,一方面里用了hdfs的高可靠性和可伸缩行,另外一方面里用 了BigTable的高效数据组织形式.可以说HBase为海量数据的real-time相应提供了很好的一个开源解决方案…

C++/C union使用记一下锅

//首先&#xff0c;学习编程一定要记得加几个群或者加几个讨论组&#xff0c;因为这样你才能不断地进步还有吵架/滑稽 记一下 关于使用union结构体时遇到的一些坑 To zero-initialize an object of type T means: — if T is a scalar type (3.9), the object is set to the va…

推荐60+ Flex开发参考网站

推荐60 Flex开发参考网站 下面是一些好的Flex开发的网站或者Flex资源&#xff0c;如果你使用Flex开发&#xff0c;可以参考一下。 网上找的&#xff0c;可以参考参考&#xff01;呵呵 新手入门参考: Adobe Flex 3 - adobe.comAdobe Flex Sample Applications - adobe.comVideo …

PAT(甲级)2020年秋季考试 7-4 Professional Ability Test

解题思路&#xff1a; 1.用拓扑排序判断给定的图是否是有向无环图(DAG) 在这个过程当中&#xff0c;对于入度为0的结点&#xff0c;在布尔数组中标记是初始结点 通过入队的结点个数是否等于总个数判断是不是DAG 注意&#xff1a;虽然有队列&#xff0c;但是不需要inq[]数组…

TestNG:org.openqa.selenium.os.UnixProcess$SeleniumWatchDog错误

在TestNG运行自动化测试用例的时候&#xff0c;浏览器FireFox正确打开&#xff0c;可是在测试用例运行完成后&#xff0c;我调用的是webdriver.quit()关闭程序的&#xff0c;结果却报以下错误&#xff1a; Sep 25, 2014 4:19:32 PM org.openqa.selenium.os.UnixProcess$Seleniu…

项目经理修炼手册 2.1.2 项目经理的基本功

具备以上素质的人&#xff0c;大体上可以算是具有基本的程序员素质了&#xff0c;但是想从程序员成为项目经理&#xff0c;必然还需要有一点进步&#xff0c;那额外的这些素质都有哪些呢&#xff1f; 曾经有人力资源的朋友问我要人&#xff0c;我介绍了几个技术上很不错的人&am…

CSS3动画过渡的jquery动态弹出框插件

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/w178191520/article/details/84111711 在线演示 本地下载

PAT(甲级)2021年春季考试 7-4 Recycling of Shared Bicycles

解题思路&#xff1a; 先用Floyd算法求出全员最短路径矩阵。 然后使用DFS进行遍历&#xff0c;遍历的原则是就近贪心&#xff0c;对于每一个点先遍历离他最近的未访问点。 记录访问点的个数&#xff0c;同时用数组存放已访问点&#xff0c;如果访问点的个数不等于输入点数1(…

JAVA抽象类和接口的区别【附经典分析用例Door】

这篇文章对抽象类和接口说的很详细&#xff0c;希望对大家有所帮助.  abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制&#xff0c;正是由于这两种机制的存在&#xff0c;才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类…

sql 2005提示未能加载包Microsoft SQL Management Studio Package

被360隔离了&#xff0c;请到360恢复区恢复。转载于:https://www.cnblogs.com/janealer/p/4238743.html

puppeteer爬虫的奇妙之旅

(爬虫)[puppeteer|] 爬虫又称网络机器人。每天或许你都会使用搜索引擎&#xff0c;爬虫便是搜索引擎重要的组成部分&#xff0c;爬取内容做索引。现如今大数据&#xff0c;数据分析很火&#xff0c;那数据哪里来呢&#xff0c;可以通过网络爬虫爬取啊。那我萌就来探讨一下网络爬…

(C++)异常退出情况合集(持续更新中)

1.一个有输入的程序&#xff0c;还没做任何输入就自己运行结束了 原因&#xff1a;将长度为10的6次方的整型数组定义在main函数内 2.点击编译运行&#xff0c;显示源文件未编译 原因&#xff1a;定义了一个10的9次方长度的整型数组(虽然在main函数外)

Resin介绍及其使用配置

Resin是一个提供高性能的&#xff0c;支持 Java/PHP 的应用服务器。目前有两个版本&#xff1a;一个是GPL下的开源版本&#xff0c;提供给一些爱好者、开发人员和低流量网站使用&#xff1b;一种是收费的专业版本&#xff0c;增加了一些更加适用于生产环境的特性。 Resin的一些…

Linux基础教程之linux文件权限深度解读

基本命令——来源于马哥教育官网1.cut: cat /etc/passwd | cut -d’:’ -f7| uniq -c| sort -nr 2.authconfig 修改加密方式–passalgosha256 — update3.scp 上传文件-r dir ip:path 传目录file ip:path传文件-P port 指定端口4.rsync 同步文件-avz 源文件 ip:pathscp和rsync都…

浙江大学软件学院2020年保研上机模拟练习 7-4 Shopping With Coupons

目录 解题思路演进过程 第一次程序 第二次程序 第三次程序 解题思路演进过程 首先是题目的理解上&#xff1a;有n个商品&#xff0c;n张优惠券&#xff0c;实际上能买的商品个数最多就是n*n,为啥呢&#xff0c;这题默认是买一个商品必须用一张券&#xff0c;而且一个商品每…

erlang supervisor simple_one_for_one实例

http://www.cnblogs.com/little-ant/p/3196201.html simple_one_for_one vs one_for_one: 相同点&#xff1a; 这种Restart Strategy和one_for_one基本相同(即当一个child process挂掉后&#xff0c;仅仅重启该child process 而不影响其他child process)。 异同点&#xff1a; …

sql isnull函数的使用(转载)

sql isnull函数的使用 ISNULL 使用指定的替换值替换 NULL。 语法 ISNULL ( check_expression , replacement_value ) 参数 check_expression 将被检查是否为 NULL的表达式。check_expression 可以是任何类型的。 replacement_value 在 check_expression 为 NULL时将返回的表达…

Error creating bean with name 'defaultHandlerMapping' defined in ServletContext resource

未解决转载于:https://www.cnblogs.com/hqsbrx/p/9969449.html

priority_queue 结构体的优先级设置

目标&#xff1a;使用结构体Node类型的优先队列&#xff0c;让其按照我们希望的顺序进行排序。 预备知识&#xff1a;会结构体的定义&#xff0c;和结构体类型的优先队列的定义&#xff0c;知道优先队列默认是最大堆排序(即top()得到的是最大的元素) 要做的事&#xff1a;在结…

PNG透明兼容IE6的几种方法

png透明针对IE6一直是件挺麻烦的事情&#xff0c;使用的方法也是各有不同&#xff0c;大多的原理是用IE的滤镜来解决的。 语法&#xff1a;filter : progid:DXImageTransform.Microsoft.AlphaImageLoader ( enabledbEnabled , sizingMethodsSize , srcsURL ) enabled : 可选项。…

ntohs的一个简单实现(将网络流中用两个字节16进制表示的资源数(如DNS)和长度转换为整形)...

我们知道在由于大端机和小端机导致网络字节序和主机序有可能是有差异的&#xff0c;我们可以使用系统的ntohs,ntohl,htons和htonl这些处理函数进行转换&#xff0c;下面是我写的一个关于ntohs在处理小端机字节序转换的函数的简单实现. 思想大致如下: 用u_int16_t的2字节16位的整…

循环获取结构体中的健名与值的实现

为什么80%的码农都做不了架构师&#xff1f;>>> type Person struct {Name stringAge int }func main() {a : &Person{"Name", 1}v : reflect.ValueOf(a).Elem() //a需要是引用k : v.Type()for i : 0; i < v.NumField(); i {key : k.Field(i)…

PAT(甲级)2020年春季考试 7-4 Replacement Selection

这种复杂的模拟题&#xff0c;对于我这种菜鸡&#xff0c;只能是根据自己的理解&#xff0c;去把题目给演示出来&#xff0c;然后结合测试用例&#xff0c;一点一点debug打印输出&#xff0c;的确耗时&#xff0c;所以考试要是遇到就放最后吧。 把这题做出来&#xff0c;我的一…

On/Off FlipSwitch 按钮

https://proto.io/freebies/onoff/转载于:https://www.cnblogs.com/ElvinLong/p/4253665.html