JavaScript发展简介

背景

  • 互联网(Internet):诞生于20世纪60年代,美苏冷战时期。
  • 万维网(WWW/Web/W3):蒂姆·伯纳斯·李(Tim Berners-Lee)在1989年12月发明了World Wide Web,即万维网(WWW)。1991年,万维网在Internet上首次露面,当时引起全球轰动。
  • 网景:1993年,美国一个浏览器“Mosaic”燃爆Internet。1994年4月,该浏览器开发团队的核心人物马克·安德森和Silicon Graphic公司的创始人吉姆·克拉克成立“MOSAIC Communication Corp”。但是由于他们此时没有浏览器版权及技术,只能重写浏览器。1994年10月13日,该公司开发的浏览器Mosaic Netscape 0.9发布,虽然仍是beta版本,该浏览器获得重大成功,成为当时最热门的浏览器。1994年11月14日,为了避免和NCSA的商标拥有权问题,更名为网景通信公司(Netscape Communications Corporation)。同年12月15日,网景浏览器1.0正式版发布,软件改名为网景导航者(Netscape Navigator),并且迅速占领市场。
  • 微软:在网景浏览器疯狂吸金的时候,引起了微软的注意,它收购了Mosaic的授权,以此为基础研发出Internet Explorer,江湖人称IE。至此之后,网景与微软开始了著名的“浏览器大战”。
  • Sun:创建于1982年,主要做工作站(一种高端的通用微型计算机)和服务器。1986年在美国成功上市,1993年进入财富500强。1995年5月,Sun公司将Oak语言改名为Java,并且正式推出市场,Sun公司大肆宣传,许诺这种语言可以”一次编写,到处运行”(Write Once, Run Anywhere)。
  • 诞生背景:1994年,也就是0.9版本发布时,该浏览器只能用来浏览,不具备与访问者互动的能力。此时网景公司也意识到自己急需一种网页脚本语言,使得浏览器可以与网页互动。 网页脚本语言到底是什么语言?网景公司当时有两个选择:一个是采用现有的语言,比如Perl、Python、Tcl、Scheme等等,允许它们直接嵌入网页;另一个是发明一种全新的语言。这两个选择各有利弊。第一个选择,有利于充分利用现有代码和程序员资源,推广起来比较容易;第二个选择,有利于开发出完全适用的语言,实现起来比较容易。到底采用哪一个选择,网景公司内部争执不下,管理层一时难以下定决心。时间来到了1995年,Java的推出让网景公司动了心,于是决定与Sun公司结盟,想让浏览器支持Java以applet(小程序)的形式直接在浏览器中运行。

诞生

1995年4月,网景公司聘用了34岁的程序员,Brendan Eich(布兰登·艾奇)。Brendan Eich的主要方向和兴趣是函数式编程,网景公司招聘他的目的,是研究将Scheme语言作为网页脚本语言的可能性。Brendan Eich本人也是这样想的,以为进入新公司后,会主要与Scheme语言打交道。仅仅一个月之后,1995年5月,网景公司做出决策,未来的网页脚本语言必须”看上去与Java足够相似,但是比Java简单,使得非专业的网页作者也能很快上手”。这个决策实际上将Perl、Python、Tcl、Scheme等非面向对象编程的语言都排除在外了。Brendan Eich被指定为这种”简化版Java语言”的设计师。但是,他对Java一点兴趣也没有。为了应付公司安排的任务,他只用10天时间就把Javascript设计出来了。由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。
多年以后,Brendan Eich还是看不起Java。
他说:”Java(对Javascript)的影响,主要是把数据分成基本类型(primitive)和对象类型(object)两种,比如字符串和字符串对象,以及引入了Y2K问题。这真是不幸啊。”
何为Y2K问题?
根据设想,Date.getYear()返回的应该是年份的最后两位:

1
2
var date1 = new Date(1999,0,1);
  var year1 = date1.getYear(); // 99

但是实际上,对于2000年,它返回的是100!

1
2
var date2 = new Date(2000,0,1);
  var year2 = date2.getYear(); // 100

这个问题完全来源于Java,因为Javascript的日期类直接采用了java.util.Date函数库。Brendan Eich显然很不满意这个结果,这导致后来不得不添加了一个返回四位数年份的Date.getFullYear()函数。如果不是公司的决策,Brendan Eich绝不可能把Java作为Javascript设计的原型。作为设计者,他一点也不喜欢自己的这个作品:

1
"与其说我爱Javascript,不如说我恨它。它是C语言和Self语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:'它的优秀之处并非原创,它的原创之处并不优秀。'(the part that is good is not original, and the part that is original is not good.)"

设计思路

  • 借鉴C语言的基本语法
  • 借鉴Java语言的数据类型和内存管理
  • 借鉴Scheme语言,将函数提升到”第一等公民”(first class)的地位
  • 借鉴Self语言,使用基于原型(prototype)的继承机制

所以,Javascript语言实际上是两种语言风格的混合产物—-(简化的)函数式编程+(简化的)面向对象编程。这是由Brendan Eich(函数式编程)与网景公司(面向对象编程)共同决定的。

标准化

因为 JavaScript 1.0 的成功,Netscape 在 Netscape Navigator 3.0 中发布了 1.1 版。此时,微软进军浏览器市场,发布了 IE 3.0 并搭载了一个 JavaScript 的克隆版,叫做 JScript(这样命名是为了避免与 Netscape 潜在的许可纠纷)。微软步入 Web 浏览器领域的这重要一步虽然令其声名狼藉,但也成为 JavaScript 语言发展过程中的重要一步。
在微软进入后,有 3 种不同的 JavaScript 版本同时存在:Netscape Navigator 3.0 中的 JavaScript、IE 中的 JScript 以及 CEnvi 中的 ScriptEase。与 C 和其他编程语言不同的是,JavaScript 并没有一个标准来统一其语法或特性,而这 3 种不同的版本恰恰突出了这个问题。随着业界担心的增加,这个语言的标准化显然已经势在必行。
1997 年,JavaScript 1.1 作为一个草案提交给欧洲计算机制造商协会(ECMA)。第 39 技术委员会(TC39)被委派来“标准化一个通用、跨平台、中立于厂商的脚本语言的语法和语义”(http://www.ecmainternational.org/memento/TC39.htm)。由来自 Netscape、Sun、微软、Borland 和其他一些对脚本编程感兴趣的公司的程序员组成的 TC39 锤炼出了 ECMA-262,该标准定义了名为 ECMAScript 的全新脚本语言。
在接下来的几年里,国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 作为标准(ISO/IEC-16262)。从此,Web 浏览器就开始努力(虽然有着不同的程度的成功和失败)将 ECMAScript 作为 JavaScript 实现的基础。

JavaScript实现

尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:

  • 核心部分(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

ECMAScript及版本历史

ECMA-262 标准(第 2 段)的描述表示:

1
“ECMAScript 可以为不同种类的宿主环境提供核心的脚本编程能力,因此核心的脚本语言是与任何特定的宿主环境分开进行规定的... ...”

简单来说就是,ECMAScript 并不与任何具体浏览器相绑定。其主要描述了以下内容:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 运算符
  • 对象
    ECMAScript 分成几个不同的版本,它是在一个叫做 ECMA-262 的标准中定义的,其主要版本包括以下:
  • ECMA-262第一版,1997年06月,在本质上与 Netscape 的 JavaScript 1.1 是一样,只是把所有与浏览器相关的代码删除了,此外还有一些小的调整。首先,ECMA-262 要求对 Unicode 标准的支持(以便支持多语言)。第二,它要求对象是平台无关的(Netscape 的 JavaScript 1.1 事实上有不同的对象实现,例如 Date 对象,是依赖于平台)。这是 JavaScript 1.1 和 1.2 为什么不符合 ECMA-262 规范第一版的主要原因。
  • ECMA-262第二版,1998年06月,大部分更新本质上是编辑性的。这次标准的更新是为了与 ISO/IEC-16262 的严格一致,也并没有特别添加、更改和删除内容。ECMAScript 一般不会遵守第二版。
  • ECMA-262第三版,1999年12月,是该标准第一次真正的更新。它提供了对字符串处理、错误定义和数值输出的更新。同时,它还增加了正则表达式、新的控制语句、try…catch 异常处理的支持,以及一些为使标准国际化而做的小改动。一般来说,它标志着 ECMAScript 成为一种真正的编程语言。
  • ECMA-262第四版,预计2008年8月发布,由于关于语言的复杂性出现分歧,发布前被放弃,其中的部分精华成为了第5版本及Harmony(next版本)的基础。
  • ECMA-262第五版,2009年12月,新增“严格模式(strict mode)”,提供更彻底的错误检查。澄清了许多第3版本的模糊规范,增加了部分新功能,如getters及setters,支持JSON以及在对象属性上更完整的反射。
  • ECMA-262第5.1版,2011年06月,成为ISO国际标准(ISO/IEC16262:2011)。到2012年底,所有主流浏览器都支持该版本的所有功能。
  • ECMA-262第六版,2015年06月发布,并更名为“ECMAScript 2015”,简称ES6。这是因为TC39委员会计划,以后每年发布一个ECMAScirpt的版本,下一个版本在2016年发布,称为“ECMAScript 2016”。ES6增添了许多必要的特性,新功能包括:模块和类以及一些实用特性,例如Maps、Sets、Promises、生成器(Generators)等。
  • ES2016、ES2017、ES.Next…

DOM

Document Object Model,文档对象模型。是W3C组织推荐的处理可扩展标志语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM。在 1998 年,W3C 发布了第一级的 DOM 规范。这个规范允许访问和操作 HTML 页面中的每一个单独的元素。所有的浏览器都执行了这个标准,因此,DOM 并不存在兼容性问题。DOM 可被 JavaScript 用来读取、改变 HTML、XHTML 以及 XML 文档。DOM 被分为不同的部分(核心、XML及HTML)和级别(DOM Level 1/2/3)。

  • 核心 DOM:针对任何结构化文档的标准模型,例如遍历DOM树、添加新节点、删除节点、修改节点
  • XML DOM:针对 XML 文档的标准模型,其主要针对XML节点对象(Node)
  • HTML DOM: 针对 HTML 文档的标准模型,其主要针对HTML标签对象,如Body、Form、Image
  • 1级DOM在1998年10月份成为W3C的提议,由DOM核心与DOM HTML两个模块组成。DOM核心能映射以XML为基础的文档结构,允许获取和操作文档的任意部分。DOM HTML通过添加HTML专用的对象与函数对DOM核心进行了扩展。
  • 2级DOM通过对象接口增加了对鼠标和用户界面事件(DHTML长期支持鼠标与用户界面事件)、范围、遍历(重复执行DOM文档)和层叠样式表(CSS)的支持。同时也对DOM 1的核心进行了扩展,从而可支持XML命名空间。
  • 3级DOM通过引入统一方式载入和保存文档和文档验证方法对DOM进行进一步扩展,DOM3包含一个名为“DOM载入与保存”的新模块,DOM核心扩展后可支持XML1.0的所有内容,包括XML Infoset、 XPath、和XML Base。

BOM

Browser Object Model,浏览器对象模型。浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。
1999年,Internet Explorer对BOM进行扩展以包括ActiveX对象类,可以通过JavaScript来实现ActiveX对象,为日后Ajax的出现埋下伏笔。

Ajax

Asynchronous Javascript And XML,异步JavaScript和XML。1999年W3C发布第四代HTML标准,同年微软推出用于异步数据传输的ActiveX,随即各大浏览器厂商模仿实现了XMLHttpRequest,这标志着Ajax的诞生,但是Ajax这个词是在六年后(2005年)问世的,特别是在谷歌使用Ajax技术打造了Gmail和谷歌地图之后,Ajax获得了巨大的关注。
在2005年之前,也即Ajax问世之前,Web应用可以称之为Web 1.0时代。此时的Web应用甚至不能称为应用,顶多算Web网页。
Web 1.0时代的网页大致有以下三个特点:

  • 所有的网页都基于HTML页面,因为没有任何手段可以控制局部内容的显示和隐藏,因此任何局部的变化哪怕只多出一个标点符号,都只能重新下载一个新的页面
  • 计算任务只能在服务端实现。由于网速限制,与服务器通信的过程是非常缓慢的,并且此过程是同步阻塞的,于是会出现这样的场景:用户提交一个表单,然后整个页面消失,浏览器呈现白屏,经过漫长的等待,浏览器渲染出一个和之前一模一样的页面,只不过输入框旁边多了一排红色小字:用户名错误
  • 所有页面都是静态的,这意味着一个电商网站有一千种商品,哪怕页面布局一模一样,也必须写一千个单独的页面
    Ajax是Web网页迈向Web应用的关键技术,它标识着Web2.0时代的到来,2006年,XMLHttpRequest被W3C正式纳入标准。
    由于Web 1.0时代,网页的各种受限,导致早起的网页应用由后端主导,前端顶多能做的也就是操作DOM。
    起初制约Web开发从后到前的因素很简单,就是前端很多事干不了或干不好,当时的浏览器性能弱,标准化程度低。特别是占据大量市场份额的IE,不仅ugly,并且buggy。
    这时候前端开发者开始尝试推出一些框架来做出改变。

Prototype

Prototype框架是由Sam Stephenson在2005年2月推出的,它是最受欢迎的Ajax框架之一。Prototype框架以面向对象的方式封装js代码,引入了前端类的概念,大大简化了客户端的开发工作。

JQuery

2005年8月,John Resig提议改进Prototype的“Behaviour”库,他的提议主要包括三点:

  • 为元素注册一个事件
  • 为不同的元素注册不同的事件
  • 为不断变化的元素注册不同的事件
    他的这三点提议,也是jQuery语法设计的最初雏形。2006年1月14日,John Resig正式发布了jQuery,jQuery主要用于操作DOM,其优雅的语法、符合直觉的事件驱动型的编程思维使其极易上手,因此很快风靡全球,大量基于jQuery的插件构成了一个庞大的生态系统。
    JQuery整体架构如下图:

V8

由于IE为主导的浏览器性能实在太差,google于2008年推出V8引擎。V8引擎带来的性能提升最要在下面三个方面:

  • 快速属性访问
  • 动态生成机器码
  • 高效的垃圾回收
    现代浏览器的崛起终结了微软的垄断时代,前端的计算能力一下子变得过剩了。标准组织也非常配合的在2009年发布了第五代JavaScript,前端的装备得到了整体性的提高,前端界如同改革开放走进了一个令人目不暇接的新时代。
    2009年AngularJS诞生,随后被谷歌收购。2010年backbone.js诞生。2011年React和Ember诞生。2014年Vue.js诞生…,前后端分离可谓大势所趋。
    前后端分离,一般指后端只负责数据,前端负责其余工作。前后端沟通的数据通过接口规范定义。早期Web应用使用Web Service技术实现,现代Web应用或者说Web2.0之后的应用,一般通过RESTful架构实现。

Knockout

knockout是一个轻量级的UI类库,通过MVVM模式使JavaScript前端UI简单化。knockout有四大重要概念:

  • 声明式绑定:使用简明移读的语法很容易地将模型(model)数据关联到dom元素上。
  • UI界面自动刷新:当宁的模型状态(model state)改变时,您的UI将自动更新
  • 依赖跟踪:为转变和联合数据,在你的模型数据之间隐式建立关系
  • 模板:为你的模型数据快速编写复杂的可嵌套的UI

Backbone

backbone将数据呈现为模型, 你可以创建模型、对模型进行验证和销毁,甚至将它保存到服务器。 当UI的变化引起模型属性改变时,模型会触发”change”事件; 所有显示模型数据的视图会接收到该事件的通知,继而视图重新渲染。 你无需查找DOM来搜索指定id的元素去手动更新HTML。 — 旦模型改变了,视图便会自动变化。其主要组成包括:

  • model:创建数据,进行数据验证,销毁或者保存到服务器上
  • collection:可以增加元素,删除元素,获取长度,排序,比较等一系列工具方法,说白了就是一个保存models的集合类
  • view:绑定html模板,绑定界面元素的事件,初始的渲染,模型值改变后的重新渲染和界面元素的销毁等

AngularJS 1

AngularJS 1 诞生于2009年,是一款前端架构,其专注于web开发,后来杀出另一个基于ng 1的框架ionic,才让ng 1支持移动开发。其比较核心的一些特性包括:

  • MVC
  • 模块化
  • 指令系统
  • 双向数据绑定
  • HTML模版
  • 依赖注入
    ng 1 功能很强大,一经推出世人沸腾。不过在日后的使用过程中,随之而来的是其核心特性带来的多个问题:
  • 该框架太重,虽然后期在不断的分离出部分模块
  • 其脏检测机制带来的性能问题很严重
    由于以上等问题,google推出了ng 2,ng 2与ng 1属于不同的框架,因此单独描述。

AngularJS 2

Angular 2 于2015年推出,在github上的描述为:One framework. Mobile & desktop.
ng 2的源码目前使用ts(type script)书写,开发者也可以使用js书写。ng 2主要由8个部分组成:

  • 模块 (Modules)
  • 组件 (Components)
  • 模板 (Templates)
  • 元数据 (Metadata)
  • 数据绑定 (Data Binding)
  • 指令 (Directives)
  • 服务 (Services)
  • 依赖注入 (Dependency Injection)
    由于目前现代浏览器并不完全都支持ES6+,因此现阶段的ng 2项目一般都要通过一些工具来转换。
    systemjs - 通用模块加载器,支持AMD、CommonJS、ES6等各种格式的JS模块加载
    es6-module-loader - ES6模块加载器,systemjs会自动加载这个模块
    traceur - ES6转码器,将ES6代码转换为当前浏览器支持的ES5代码。systemjs会自动加载 这个模块,常用的转码器还有babel。

与ng 1比较,ng 2其实算是一个完全的新框架,主要的区别点在于:

  • 原生移动支持
  • 支持服务端渲染
  • ng 1中,依赖注入可以在多个地方使用不同的方法来注入,例如直接通过名字、在controller注入等,而在ng 2中只能在构造函数中通过类型注入
  • ng 1无法使用ES6来正常的书写,显然已经跟不上发展的脚步了

React

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。由于 React的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。这个项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的 Web App 解决方案。衍生的 React Native 项目,目标更是宏伟,希望用写 Web App 的方式去写 Native App。如果能够实现,整个互联网行业都会被颠覆,因为同一组人只需要写一次 UI ,就能同时运行在服务器、浏览器和手机。
React主要用于构建UI,所以并不算是一套MVC框架,它主要用于V层。React 独有的 JSX 语法,跟 JavaScript 不兼容,由于此原因,最早的react项目可能需要使用Browser.js将JSX语法转为JavaScript语法。React的主要原理包括以下几点:

  • Virtual DOM,虚拟DOM。

    1
    更新Virtual DOM并不保证马上影响真实的DOM,React会等到事件循环结束,然后利用内部diff算法,通过当前新的dom表述与之前的作比较,计算出最小的步骤更新真实的DOM。
  • Components,组件。

    1
    DOM树上的节点叫元素,而在React的Virtual DOM上自定义的节点称为commponent。
  • State、Props 和 Render。

    1
    State属性包含定义组件所需要的一些数据,当组件数据发生变化时,可以使用props将state顺序传递下去,并且将会调用Render重现渲染真实DOM,这里只能通过提供的setState方法更新数据。

目前react这边技术栈多使用react全家桶:react+redux+react-router+less+es6+webpack等,当然还有其他,例如结合mobx使用。

Ember

Vue

Grunt

Gulp

Webpack

SystemJs

jspm

nodejs

npm

bower

yarn

RESTful

REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。Fielding将他对互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写,翻译为中文大概是”表现层状态转化”,如果一个架构符合REST原则,就称它为RESTful架构。
RESTful架构中的“表现层”,指的是资源“Resources”的表现层。所谓”资源”,就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。所谓”上网”,就是与互联网上一系列的”资源”互动,调用它的URI。”资源”是一种信息实体,它可以有多种外在表现形式。我们把”资源”具体呈现出来的形式,叫做它的”表现层”(Representation)。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对”表现层”的描述。
互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生”状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是”表现层状态转化”。客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
因此,一个RESTful架构大概要包括以下描述:

  • 每一个URI代表一种资源;
  • 客户端和服务器之间,传递这种资源的某种表现层;
  • 客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。
    因为”资源”表示一种实体,所以其对应的URI应该是名词,不应该有动词,动词应该放在HTTP协议中。

http://www.cnblogs.com/kidney/p/6079530.html
http://www.jianshu.com/p/8dc5c6aa01fc
https://www.ibm.com/developerworks/cn/web/1509_dongyue_react/index.html