当下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. 2、顺序表的实现(java代码)

    1.这里实现了简单的顺序表的,为空判断.是否已满判断,插入.删除,查询元素下标等功能 public class Linear_List { private int[] arr; //用来保存数据 pr ...

  2. OPC—— KepServer.ServerState返回值为3和OPCConfig.exe配置文件的根目录

    做开发没有对电脑的绝对管理员权限的问题,会出现很多意外,调试OPC是总是连接状态有时莫明返回3,提示 not configuration,问题在于: 没有以管理员权限运行OPCConfig.exe,导 ...

  3. 自定义View入门-绘制基础(1)

    ### 前言 说道自定义View,我们一定会想到,自定义View的绘制流程 - 测量阶段(measure) - 布局阶段(layout) - 绘制阶段(draw) 我们看到的一些炫酷的view效果,都 ...

  4. 09 (OC)* 键路径(keyPath)、键值编码(KVC)、键值观察(KVO)

    键路径在一个给定的实体中,同一个属性的所有值具有相同的数据类型.键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制. - 键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一 ...

  5. 【linux】【NodeJs】Centos7安装node-v10.16.3环境

    前言 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. https://node ...

  6. vue中关于滚动条的那点事

    vue中关于滚动条的那点事 不知道你有没有遇到过这种情况,有时当页面切换时,滚动条不在页面的顶端.最近半路加入一个项目,就遇到这种情况.(若只是为了解决此问题,可直接翻到最下方)下面谈谈解决此问题的过 ...

  7. Java 文章链接

    Java表单验证封装类 https://www.cnblogs.com/linjiqin/archive/2013/11/18/3429424.html 微信企业号接入JDK6和JDK7及JDK8加解 ...

  8. 【ADO.NET基础-数据加密】第一篇(加密解密篇)

    可以采用下面的函数实现密码的加密 public static string EncryptString(string str) { //密文 string key = "www"; ...

  9. c++ 对特定进程的内存监控

    在工具实现的过程中,遇到了内存爆了的问题,部分模型的规模可以达到10的100次方方甚至1000次方.(工具的主要算法涉及到了递归,递归深度会很深,所以也用到了ulimit修改栈空间来缓解爆栈的问题,治 ...

  10. TouchListener PK OnTouchEvent + 多点触碰

    1.基于监听的TouchListener 代码示例: 实现效果图: 实现代码: main.xml <RelativeLayout xmlns:android="http://schem ...