当下JavaScript越来越流行,成为长期霸语言榜前三的语言。但是实际上JavaScript是一个很丑陋有很多槽点的语言,这就是为什么新出了那么多框架(从jQuery到Vue)以及海尔斯伯格大大推出新流行语言的Type Script的直接原因,避免大家去直接用JavaScript写代码。虽然这几年随着ECMAScript 6(ES6)推出,JavaScript逐渐变得好用起来,但是JavaScript确实一直存在这一些挥之不去的痛。

本文作何就来和大家一起细数下JavaScript的一些语言痛点,知短而成长也是成功法则之一。首先申明我们不是攻击JS语言和JS的码农们(惹不起),只是希望以此让大家更加了解JS,写出更好更高效的JS代码来。

1:有问题的ASI实施

ASI机制问题,现在存在争议。JavaScript有一种称为自动分号插入(ASI)的机制,如果需要,会自动在你的代码中插入分号。JS的语言结束可以使用分号;

doSomething();

但是分号可以省略,如果你不添加分号的话,ASI会自动判断,并且自动给你添加上分号。

但是ASI实现是有问题的,如果不是熟悉ASI的机制,某些情况下ASI机制会破坏你的代码,在不该中断地方给你中断,该中断地方又不会中断,就很尴尬了,而且出问题来很难调试。

你可以选择忽略不用它,自己一直添加分号。如果你不想手动敲,则必须熟悉ASI,避免写出引起歧义的语句,以免受边缘情况的影响。

2:有一个怪异的数字类型

与许多其他语言相反,JavaScript有一种称叫做数字类型的单数数字类型。这种类型用于整数和浮点数,对于许多开发人员来说是违反直觉的,绝大多数开发人员都是熟悉的:整数和十进制数字之间有明确区别的语言。

码农需要时常提醒自己到将所有数值操作基于浮点数来处理,并且还需要使用Math对象进行舍入和查找操作的floor()或round(),很多数字操作需要自己专门写函数,很麻烦。下面是保留二位的小数的函数。

此外,类型的数字限制只能使用53位整数,对于更大的整数,你可能需要获取库。

3:三个非值数字:Infinity,-Infinity和NaN

JavaScript有个逻辑"提示,并且继续",无效或无意义的计算(例如除零)不会导致错误或抛出异常,而是产生三个非实数值中的一个,实际上是数字类型:

所以,JS处理数字非常麻烦,并且当涉及到计算繁重的程序时,很难以追踪错误。还需要诸如isFinite,isInteger和isNaN之类的大量方法来做进行数字检查。

4:两个"空"类型:null和undefined

JS事实上有两种不同的null或nil类型,原意是为了更确定区分错误,但可能导致码农在处理时候,反而会增加很多bug。

通常,undefined指的是未初始化的变量或不存在的对象属性,并且指向故意为空的变量或对象属性null,但是如何确定他应该是null或者undefined是个问题。当涉及null用例时,typeof运算符会被破坏

typeof null; // "object"

5:破碎的抽象等式(==)算法

这里真的没什么好说的。 ==运算符背后的抽象等式算法很滑稽,打破了平等和等价关系的数学概念。

它不应该被使用。应该使用严格相等运算符===。

6:不可取的类型强制转化

在处理动态变量和松散输入时,你最终需要执行某种类型强制来完成某些操作。 JavaScript的问题在于引擎所做的隐式类型强制转化是不可取的,非常规的,并且可能导致代码中出现大量错误。

例如,在混合字符串和数字时,+运算符可能会导致一些意外结果:

13 + !0; // 14

"13" + !0; // '13true

更不用说所有这些都是有效但令人费解的语言表达:

作为开发人员,你需要通过包装类构造函数Number,Boolean和String或某些内置解析方法来坚持显式类型强制。

好消息是,被强制转化的值非常容易和直观地记住:"false,null,undefined,NaN,0和''(空)都是逻辑假,其他一切都是true"。

7:var关键字和函数范围

在ES6之后,这已不再是一个问题了。但这是对语言设计不良的证明,十多年来程序员不得不接受这样一个事实,即声明的一个变量是全局性变量。

基本上,你使用var将全局变量引入你的程序中,如果你不小心并且没有真正的块变换范围,这使得理解一些简单的方法就像使用范围一样令人费解。

在ES6之后,现在你应该完全停止使用var,而是使用提供常规块作用域的let和const,并在代码开头引入use strict指令,以防止意外的全局变量声明和其他有问题的运行时行为。

其他一些不是很重要的槽点

简而言之,下面这些只是一些容易遇到而且有学习曲线的小错误,或者只是JavaScript独特语言设计的一个特点,它具有丰富的灵活性和复杂性:

复杂和不良的继承模型

复杂使用this关键字

标准库不佳

我认为任何从Java或C#等语言进入JavaScript的程序员都搞不清JS语言混乱的类语法和用于实现类的复杂对象模型。其中大部分是由于设计不合理的约定和语法决策以适应企业开发人员,因为实际上JavaScript基于原型,而不是类,它的语法应该反映出来,但它确实增加了大多数现有开发人员熟练使用该语言的复杂性。

此外,执行JavaScript的运行时和并发模型在传统编程语言中是相当独特的,因为所有JS代码都是在事件循环运行时中使用事件驱动的非阻塞异步I/O执行的。

最后吐槽的是JavaScript这个名字也是刚开始蹭人热度,后来又非法的存在(JavaScript商标权在Oracle手里),所以避免在自己的产品或者宣传中使用它(已经有开发者收到Oracle的律师函哦),用JS或者正式的名字ECMAScript来替代。

JavaScript七宗罪和一些槽点的更多相关文章

  1. 吐槽中小民营IT企业管理七宗罪

    傲慢.妒忌.暴怒.懒惰.贪婪.贪食及色欲,电影<七宗罪>中借七个典型的命案告诉我们,人性中最丑陋的七大恶行.在实际的工作中自己对企业的经营和日常管理有了一些更深刻的认识,偏偏自己又是一个很 ...

  2. 细数 Windows Phone 灭亡的七宗罪(过程很详细,评论很精彩,但主要还是因为太慢了,生态跟不上,太贪了,厂商不愿意推广)

    曾梦想仗剑走天涯,看一看世界的繁华 年少的心有些轻狂,如今你四海为家 曾让你心疼的姑娘,如今已悄然无踪影 犹记得上大学攒钱买了第一台智能手机Lumia 520时,下载的第一首歌曲<曾经的你> ...

  3. 项目总结(一)->项目的七宗罪

    大半夜来这一份总结,心中夹杂着各种各样的心情,酸甜苦辣都有,今天为止,整个项目终于完结了,对于这样一个本可以正而八经吃吃薯片,看看毛片就可以完成项目,最后演变成一个一月之内连续加班105个小时的项目, ...

  4. 悲催的IE6 七宗罪大吐槽(带解决方法)第三部分

    五:文字溢出bug(注释bug) 1.在以下情况下将会引起文字溢出bug 一个容器包含2两个具有“float”样式的子容器. 第二个容器的宽度大于父容器的宽度,或者父容器宽度减去第二个容器宽度的值小于 ...

  5. 悲催的IE6 七宗罪大吐槽(带解决方法)第二部分

    三.position:fixed无效 今天在IE6上遇到一个bug,本来想做一个消息提示框,让他在页面右上角停留一段时间后消失,这段时间内提示框随着页面的下拉一直出现在浏览器可见区的顶部,于是我用到了 ...

  6. 悲催的IE6 七宗罪大吐槽(带解决方法)第一部分

    一.奇数宽高 悲剧的IE6啊,为何有如此多bug,但用户市场又那么大,真让我们搞网站的纠结.今天就遇到了一个非常奇怪但又很细节的一个bug,一个外部的相对定位div,内部一个绝对定位的div(righ ...

  7. 【DSP开发】德州仪器达芬奇五年之路七宗罪,嵌入式处理器架构之争决战2012

    芯片是产业链上游重要的一个环节,一颗小小的芯片具有极高的技术含量和价值,半导体行业每年都会有一个各大厂商营业额的排名,除去2009年,常年盘踞在前三名位置的分别是英特尔,三星半导体和德州仪器,英特尔凭 ...

  8. JavaScript的由来, 浏览器的20年

    在很久以前那时候还没有Yahoo,Google....人们还在用28.8kbit/s的"猫"上网, 用户注册或者登录的时候所有的验证都是在服务器验证的, 如果用户注册的时候用户名或 ...

  9. 一文告诉你Java日期时间API到底有多烂

    前言 你好,我是A哥(YourBatman). 好看的代码,千篇一律!难看的代码,卧槽卧槽~其实没有什么代码是"史上最烂"的,要有也只有"史上更烂". 日期是商 ...

随机推荐

  1. MySql(二)_NHibernateHelper管理会话工厂

    1.定义接口的好处: (1) 清楚的看到里面有哪些方法: ( 2 )  可以更换实现类:Nhibernate实现件可以更换: Manger文件夹(另外两个是Model.Mappings文件夹) 首先M ...

  2. iOS -打包上传成功,在"构建版本"一直刷不出来

    今天提交版本到appstore,构建版本一直不出来,等了一天也没有出来,其实就是权限问题,iOS13 来了,所以面临的问题随之而来,苹果给邮箱发了这段话: Dear Developer,We iden ...

  3. [Leetcode] 第324题 摆动排序II

    一.题目描述 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums ...

  4. ReentrantLock API

    java可重入锁,简单几个小案例,测试特性. 1.尝试锁  tryLock package com.cn.cfang.ReentrantLock; import java.util.concurren ...

  5. Centos 7 配置tomcat服务器

    1.首先查看当前系统版本 uname -a 2.安装之前查看系统是否安装了java rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 如果没 ...

  6. connection pool exhausted

    1.发现问题 生产环境发现有一些redis报错日志 connection pool exhausted.如果redis中没有数据 就直接回源 查DB.暂时不会有什么大问题.中文意思是连接池耗尽. 2. ...

  7. 看完您如果还不明白 Kerberos 原理,算我输!

    系统环境 操作系统:CentOS 6 或 CentOS 7 JDK 版本:1.8.0_151 Ambari 版本:2.6.1 HDP 版本:2.6.4.0 扩展链接 Kerberos原理--经典对话 ...

  8. Maven 梳理 - maven新建web项目提示"javax.servlet.http.HttpServlet" was not found on the Java Build Path

    方法一: <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api&l ...

  9. Excel VBA入门(十)用户窗体开发

    VBA 中的用户窗体就是指带 UI 的用户界面,在运行的时候会单独弹出一个窗口,类似于在 windows 系统中运行的一个可执行程序一样(这个说法不太严谨,因为可执行程序也可能是只有命令窗口而没有 U ...

  10. webpack原理

    webpack早就已经在前端领域大放异彩,会使用和优化webpack也已经是中.高级工程师必备技能,在此基础之上再对webpack的原理进行理解和掌握,必定会在未来的开发中事半功倍.若是对于webpa ...