JavaScript七宗罪和一些槽点
当下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七宗罪和一些槽点的更多相关文章
- 吐槽中小民营IT企业管理七宗罪
傲慢.妒忌.暴怒.懒惰.贪婪.贪食及色欲,电影<七宗罪>中借七个典型的命案告诉我们,人性中最丑陋的七大恶行.在实际的工作中自己对企业的经营和日常管理有了一些更深刻的认识,偏偏自己又是一个很 ...
- 细数 Windows Phone 灭亡的七宗罪(过程很详细,评论很精彩,但主要还是因为太慢了,生态跟不上,太贪了,厂商不愿意推广)
曾梦想仗剑走天涯,看一看世界的繁华 年少的心有些轻狂,如今你四海为家 曾让你心疼的姑娘,如今已悄然无踪影 犹记得上大学攒钱买了第一台智能手机Lumia 520时,下载的第一首歌曲<曾经的你> ...
- 项目总结(一)->项目的七宗罪
大半夜来这一份总结,心中夹杂着各种各样的心情,酸甜苦辣都有,今天为止,整个项目终于完结了,对于这样一个本可以正而八经吃吃薯片,看看毛片就可以完成项目,最后演变成一个一月之内连续加班105个小时的项目, ...
- 悲催的IE6 七宗罪大吐槽(带解决方法)第三部分
五:文字溢出bug(注释bug) 1.在以下情况下将会引起文字溢出bug 一个容器包含2两个具有“float”样式的子容器. 第二个容器的宽度大于父容器的宽度,或者父容器宽度减去第二个容器宽度的值小于 ...
- 悲催的IE6 七宗罪大吐槽(带解决方法)第二部分
三.position:fixed无效 今天在IE6上遇到一个bug,本来想做一个消息提示框,让他在页面右上角停留一段时间后消失,这段时间内提示框随着页面的下拉一直出现在浏览器可见区的顶部,于是我用到了 ...
- 悲催的IE6 七宗罪大吐槽(带解决方法)第一部分
一.奇数宽高 悲剧的IE6啊,为何有如此多bug,但用户市场又那么大,真让我们搞网站的纠结.今天就遇到了一个非常奇怪但又很细节的一个bug,一个外部的相对定位div,内部一个绝对定位的div(righ ...
- 【DSP开发】德州仪器达芬奇五年之路七宗罪,嵌入式处理器架构之争决战2012
芯片是产业链上游重要的一个环节,一颗小小的芯片具有极高的技术含量和价值,半导体行业每年都会有一个各大厂商营业额的排名,除去2009年,常年盘踞在前三名位置的分别是英特尔,三星半导体和德州仪器,英特尔凭 ...
- JavaScript的由来, 浏览器的20年
在很久以前那时候还没有Yahoo,Google....人们还在用28.8kbit/s的"猫"上网, 用户注册或者登录的时候所有的验证都是在服务器验证的, 如果用户注册的时候用户名或 ...
- 一文告诉你Java日期时间API到底有多烂
前言 你好,我是A哥(YourBatman). 好看的代码,千篇一律!难看的代码,卧槽卧槽~其实没有什么代码是"史上最烂"的,要有也只有"史上更烂". 日期是商 ...
随机推荐
- 3.1、双向循环链表(java实现)
1.创建节点类 public class CNode<T> { public CNode prev; public CNode next; public T data; public CN ...
- StringBuilder和StringBuffer的区别
Java中StringBuilder和StringBuffer的区别分析 StringBUilder是线程不安全的(线程同步访问的时候会出问题),但是效率相对较高. (String类型使用加号进行拼接 ...
- 浅谈PHP反序列化漏洞原理
序列化与反序列化 序列化用途:方便于对象在网络中的传输和存储 0x01 php反序列化漏洞 在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等. 常见的序列化格式: ...
- 磁盘告警之---神奇的魔法(Sparse file)
一.问题来源 半夜钉钉接到告警,某台机器的磁盘使用率少于20%,于是迷糊中爬起来,咔咔咔 find / -size +1G,咔咔咔,把几个只有4-5G的日志文件echo空值了一下,然后吓蒙了,刚刚 ...
- SpringCloud学习笔记(6):使用Zuul构建服务网关
简介 Zuul是Netflix提供的一个开源的API网关服务器,SpringCloud对Zuul进行了整合和增强.服务网关Zuul聚合了所有微服务接口,并统一对外暴露,外部客户端只需与服务网关交互即可 ...
- django配置静态文件的两种方法
方法一:按照django配置静态文件的方法,可以在APP应用目录下创建一个static的文件夹,然后在static文件夹下创建一个和APP同名的文件夹,如我有一个blog的django项目,在下面有一 ...
- QCustomplot使用分享(八) 绘制图表-加载cvs文件
目录 一.概述 二.效果图 三.源码讲解 1.源码结构 2.头文件 3.移动游标 4.设置坐标轴矩形个数 5.添加图表数据 6.设置折线图类型 6.其他函数 四.测试方式 1.测试工程 2.测试文件 ...
- Docker笔记(十一):Dockerfile详解与最佳实践
Dockerfile是一个文本文件,包含了一条条指令,每条指令对应构建一层镜像,Docker基于它来构建一个完整镜像.本文介绍Dockerfile的常用指令及相应的最佳实践建议. 1. 理解构建上下文 ...
- 百度脑图-离线版(支持Linux、Mac、Win)
免费好用的思维导图软件(在线版) 离线版:桌面版脑图是基于百度脑图的本地化版本,帮助你在没有互联网环境的情况下,依然可以使用脑图工具. 百度脑图帮助你进行思维导图,可以运用于学习.写作.沟通.演讲.管 ...
- 新手学习Git之在本地使用Git
每个开发人员应该都会一个版本管理工具,在Git和SVN中,我选择以Git,以下是我的一些心得 什么是 Git Git是目前世界上最先进的分布式版本控制系统(没有之一). 一.Git安装 1).linu ...