最近在SegmentFault解题,一个问题比较让我比较印象深入:一个初学者试图在浏览器中导入Node.js的net模块。结果在控制台打印后是一个空对象。javascript
对于有点Javascript经验的人来讲,这是一个‘弱智’问题,怎么能够在浏览器端运行Node程序呢?由于这些Node模块通过Webpack处理, 因此变成了一个空对象,更好的处理方式应该是抛出异常.html
仔细反思一下,对于这些刚入门Javascript的或者从其余语言切换过来的开发者,他们压根就没有概念,好比Python、Ruby、Java这些语言都有强大的标准库,能够知足80%的开发需求,无论它在什么环境、什么平台运行,基本上均可以统一使用这套标准库。而Javascript目前的现状是:不一样的运行环境,API结构是割裂的。java
Javascript这门十几天开发出来的、专供浏览器的语言,可能当初设计是根本就没有考虑标准库这些玩意,好比文件系统,网络等等。由于这个背景, Javascript长期不具有独立性,它深度依赖于浏览器这个运行环境, 处于一种给浏览器打辅助的角色, 因此Javascript不少年没有走出浏览器玩具语言这个范围.node
固然这既是劣势,也是优点, 如今没任何语言能撼动Javascript在浏览器中的地位。python
我想不少人跟我当初同样认为浏览器提供的Web API === Javascript的标准库, 好比console.log
、setTimeout
(下文会介绍这些功能都不在Javascript规范里面). 正如当年那些把JQuery当成‘Javascript’的人.webpack
直到NodeJS的出现,Javascript才挣脱浏览器约束,延伸到服务器领域, 再也不是一个'沙盒语言'。NodeJS定义了不少模块来支撑服务端的开发, 如fs、os、Buffer、net。可是这些API同样不是Javascript的标准、也就是说NodeJS !== Javascript.git
再到后来,学不动了,NodeJS原做者吐槽了一通NodeJS,又搞出了一个Deno, 它也会有本身标准库,会定义本身的文件系统、网络API。从名字上就暗示着这些API不可能和NodeJS兼容。Ok,如今回到文章开始那个问题,若是deno发展起来,说不定哪天又有人尝试在浏览器引用Deno的模块?github
如上图, Javascript实际上是有一层比较薄全局的、通用的、标准的、核心的API层,即标准内置对象
,这是一些语言核心的内置对象,能够全局访问。关键的是这些是标准的,它们在ECMAScript规范中被定义. 在这个基础之上,不一样的运行环境拓展了本身的API。golang
以浏览器为例:web
浏览器端的Web API是一个很是复杂API集合,上图总结了一下,基本就包含两块东西:
WebAPI基本概览:
若是你有留心查看MDN文档下面的规范引用,你会发现有些规范引用了W3C, 有些则引用了WHATWG. 到底谁说了算?
若是你掀开锅盖,就会发现这是一场闹剧. 若是前阵子有关注新闻,会看到这些标题‘WHATWG 击败 W3C,赢得 HTML 和 DOM 的控制权’、'W3C将与WHATWG合做制定最新HTML和DOM规范标准'. 大概能够猜出这两个组织之间的关系. 本文就不扯这些‘八卦’了,相关背景能够看这篇文章WHATWG 击败 W3C,赢得 HTML 和 DOM 的控制权
相对而言, 语言层则由ECMAScript规范定义的,比较独立, 近些年成果也比较显著.
这些全局基本对象数量不多, 这些对象是每一个JavaScript开发者必须掌握的.
平时咱们使用的很是频繁的Timer和Console都再也不此列.
这些对象只能知足很基本开发需求, 根本不能和其余语言的标准库相比. 固然这和语言的定位也有必定关系
标准库没有一个严格的定义,按照Wiki的说法标准库就是该语言在不一样实现中都按例提供的库, 好比Ruby官方实现cRuby和基于JVM的JRuby都按照官方标准库规范实现了标准库。 标准库怎么设计,须要包含什么内容取决于语言各自秉持的哲学和定位。 我认为标准库应该有如下特征:
至于标准库须要包含什么内容,能够参考其余语言的实现。好比:
大概分析一下,它们标准库大体都有这些内容:
大部分语言的核心都很小(C++除外),咱们学一门语言,大部分时间是花在标准库上和语言的生态上面,可是你会发现这些标准库通常都是大同小异,这就是为何有经验的开发者能够很快地入手一门语言.
显然上面这些功能大部分在NodeJS中已经实现了,鉴于NodeJS这么普遍的使用率,NodeJS能够算是事实上的标准了
显然要结合当前的背景来辩证地考虑。
有标准库有什么好处?
标准库可能会有什么问题?
如何设计标准库? 标准库推动进程可能会有什么障碍?
NodeJS已是事实上的标准, 怎么兼容现有的生态?
标准库应该包含什么内容,如何保持和社区同步?
如何把控标准库内容的尺度?
最小化的标准库容易被维护和升级,但可能出现'没什么卵用'的状况;
最大化的标准库,例如Java的标准库,几乎包含了全部的东西,开发者能够快速开发一个东西, 可是过了几年不少API就会变得过期,通常为了保持向下兼容,这些API会一直像一根刺同样卡在那里. 另外一个很是典型的反例就是PHP的标准库,这里能够看到各类风格的API.
标准库是跟随语言发布的,若是你的项目中使用了过期的API,又想升级语言版本,就须要重构项目。而使用第三方库则可能能够保持不动。
Javascript的主要战场仍是浏览器, 标准库是否应该有一个'基本版'(用于浏览器或者一些抽象操做系统的运行环境), 还有个'旗舰版'(服务端), 或者只提供一个跨越全部平台的标准库?
如何处理兼容性问题? 老旧浏览器如何Polyfill?
如何与现有的全局对象或用户模块分离?
proposal-javascript-standard-library 这是一个很是早期的语言提议,定义了如何引用标准库(built-in modules),可是没有定义标准库的内容
KV Storage: the Web's First Built-in Module Chrome在年初推出的实验性功能,尝试实现proposal-javascript-standard-library提议. 它经过下面方式来引用‘标准库’模块:
import {storage, StorageArea} from 'std:kv-storage'; // std: 前缀,和普通模块区分开来
复制代码
本文从一个SegmentFault上的一个问题开始,对比其余语言,揭露Javascript没有标准库的窘境. 接着介绍现有Javascript的API结构,介绍什么是标准库,辩证考虑标准库的优缺点,以及推行上面可能会遇到的阻碍.