分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

JS中8个常见的陷阱

发布时间:2023-09-06 02:22责任编辑:沈小雨关键词:暂无标签
译者按: 漫漫编程路,总有一些坑让你泪流满面。

  • 原文: 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‘ // 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‘ ??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]() // 10 ?Greeters[1]() // 10 ?Greeters[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 = name ???this.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、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

版权声明

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

JS中8个常见的陷阱

原文地址:http://blog.51cto.com/13957060/2317508

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved