跳至主要内容

JavaScript从零开始——入门(1)

 正好这段时间在学习JavaScript全栈,顺便把自己到目前为止的知识重新整理一下,做个自己能够理解的学习路径出来。

先从入门开始,老生常谈一下5W1H——有很大一部分,尤其是历史是引用自网道的JavaScript教程,特此声明:

入门篇wangdoc.com

What——什么是JavaScript?

各个网站、书籍、教程都写了无数次JavaScript的定义,最简单的一种说法就是:

JavaScript是一种轻量级的脚本语言。

其实这个定义到2020的今天,有一点点不太一样了,毕竟它已经发展到一个前人无法想象的地步了,如今的JavaScript不再是只能用来编写控制其他大型应用程序的“脚本”,它还可以用来构建服务器(如最常用的Web服务器等),构造移动应用(主流的iOS或者Android),甚至可以直接编写PC端桌面应用(Windows,Mactintosh以及Linux),已经是不折不扣的“全栈”语言了。

当然其实它所提供的核心语法并不算很多,只能用来做一些数学和逻辑运算,也不提供任何与I/O相关的API,而是要靠宿主环境(host)提供,所以它其实算是嵌入式(embedded)语言,现如今这诸多用途的开发,都是各大JavaScript框架的功劳:譬如服务器构建,用到了著名的Node.js;移动应用上常见的是React Native,PhoneGap/Cordova甚至jQuery Mobile;桌面应用的框架则主要是electron.js。

最后,从语法角度看,它是一种“对象模型”语言,各种宿主环境通过这个模型,描述自己的功能和操作接口,从而通过JavaScript来控制对应功能;但JavaScript并不是纯粹的“面向对象的”语言,因为它还支持其他的编程范式——如函数式编程——这就导致几乎任何问题,它都可能有多种解决的方法。


Where——JavaScript可以用在哪里?

如前所述,JavaScript的核心语法其实很精简,只包括了:

  1. 基本的语法构造:操作符、控制结构、语句等;
  2. 标准库:Array(数组)、Date(日期时间)、Math(数学库)等等。

除此之外的所有其他特性,都是由宿主所提供的API,仅仅是通过JavaScript进行调用。

如浏览器,它额外提供了如下三大类API:

  • 浏览器控制类:操作浏览器
  • DOM(文档对象模型,在Mozilla官方网站,它也属于Web API)类:操作网页的各种元素
  • Web类:实现互联网的各种功能

若是服务器(Node.js),则会提供各种和服务提供相关的API,如:

  • 文件操作API
  • 网络通信API
  • 进程和线程API
  • 性能和监控API
  • ……

而移动或者桌面应用的API,则都与操作系统特性紧密相关,如:文件操作、系统通知、硬件交互等等,有不少其实和Node.js可以提供的高度重合——我最常用的代码编辑器Visual Studio Code其实就是基于JavaScript(微软开发的JavaScript超集TypeScript)开发的。

所以现在流行的“全栈”(Full Stack)主要是基于JavaScript提出的,也是当今几乎唯一的真正全栈开发语言。

著名程序员 Jeff Atwood 甚至提出了一条 “Atwood 定律”

“所有可以用 JavaScript 编写的程序,最终都会出现 JavaScript 的版本。”
(Any application that can be written in JavaScript will eventually be written in JavaScript.)

When——JavaScript的历史?

1995年,Netscape雇佣了程序员Brendan Eich所开发,在5月份他只用了10天就设计完成了第一版——一个大杂烩,其语法有多个来源:

  • 基本语法:借鉴 C 语言和 Java 语言;
  • 数据结构:借鉴 Java 语言,包括将值分成原始值和对象两大类;
  • 函数的用法:借鉴 Scheme 语言和 Awk 语言,将函数当作第一等公民,并引入闭包;
  • 原型继承模型:借鉴 Self 语言(Smalltalk 的一种变种);
  • 正则表达式:借鉴 Perl 语言;
  • 字符串和数组处理:借鉴 Python 语言

为了保持简单,这种脚本语言缺少一些关键的功能,比如块级作用域、模块、子类型(subtyping)等等,但是可以利用现有功能找出解决办法。这种功能的不足,直接导致了后来 JavaScript 的一个显著特点:对于其他语言,你需要学习语言的各种功能,而对于 JavaScript,你常常需要学习各种解决问题的模式。而且由于来源多样,从一开始就注定,JavaScript 的编程风格是函数式编程和面向对象编程的一种混合体。

JavaScript标准的发展

最初版本叫Mocha,同年9月改为LiveScript,12月Netscape和Sun公司达成协议,改名为JavaScript。

1996年3月,Netscape Navigator 2.0浏览器正式内置了JavaScript。

1996年8月,微软模仿JavaScript开发了一种相近的语言叫JScript,内置于IE 3.0。

1996年11月,Netscape决定将JavaScript交给国际标准化组织ECMA(European Computer Manufacturers Association),期望JavaScript成为国际标准,以此抵抗微软;ECMA的39号技术委员会(Technical Committee 39,简称TC39)负责制定和审核该标准。

1997年7月ECMA发布262号标准文件(ECMA-262)第一版,规定了浏览器脚本语言的标准,并称为ECMAScript;自此,ECMAScript成为了JavaScript的规格,而JavaScript则是ECMAScript 的实现版本。

1998年6月,ECMAScript 2.0版发布。

1999年12月,ECMAScript 3.0版发布,成为了JavaScript的通行标准,得到广泛的支持。

2007年10月,ECMAScript 4.0版草案发布,由于对3.0版做了大幅升级,各方对于是否通过该标准发生了严重分歧。

2008年7月,ECMAScript 4.0开发中止,将其中涉及现有功能改善的一小部分发布为ECMAScript 3.1,不久后改名为ECMAScript 5;其他较为激进的改动,则起名为Harmony作为后续版本的开发项目。

2009年12月,ECMAScript 5.0正式发布。同时Harmany一分为二,较为可行的定名为JavaScript.next继续开发,该部分演变为ECMAScript 6;其他不是很成熟的设想视为JavaScript.next.next,考虑在更远的未来完善后推出。

2011年6月,ECMAScript 5.1发布,并且成为ISO国际标准;2012年底,所有主要浏览器都已经支持ECMAScript 5.1版的全部功能。

2013年12月,ECMAScript 6 草案发布。

2015年6月,ECMAScript 6正式发布,并更名为ECMAScript 2015;以后将每年发布一个ECMAScript版本,到2019年为止,已经发布了ECMAScript 2016 - 2019等4个主要版本。

周边的发展

1996年,样式表标准 CSS 第一版发布。

1997年,DHTML(Dynamic HTML,动态 HTML)发布,允许动态改变网页内容。这标志着 DOM 模式(Document Object Model,文档对象模型)正式应用。

1998年,Netscape 公司开源了浏览器,这导致了 Mozilla 项目的诞生。几个月后,美国在线(AOL)宣布并购 Netscape。

1999年,IE 5部署了 XMLHttpRequest 接口,允许 JavaScript 发出 HTTP 请求,为后来大行其道的 Ajax 应用创造了条件。

2000年,KDE 项目重写了浏览器引擎 KHTML,为后来的 WebKit 和 Blink 引擎打下基础。这一年的10月23日,KDE 2.0发布,第一次将 KHTML 浏览器包括其中。

2001年,微软公司时隔5年之后,发布了 IE 浏览器的下一个版本 Internet Explorer 6。这是当时最先进的浏览器,它后来统治了浏览器市场多年。

2001年,Douglas Crockford 提出了 JSON 格式,用于取代 XML 格式,进行服务器和网页之间的数据交换。JavaScript 可以原生支持这种格式,不需要额外部署代码。

2002年,Mozilla 项目发布了它的浏览器的第一版,后来起名为 Firefox。

2003年,苹果公司发布了 Safari 浏览器的第一版。

2004年,Google 公司发布了 Gmail,促成了互联网应用程序(Web Application)这个概念的诞生。由于 Gmail 是在4月1日发布的,很多人起初以为这只是一个玩笑。

2004年,Dojo 框架诞生,为不同浏览器提供了同一接口,并为主要功能提供了便利的调用方法。这标志着 JavaScript 编程框架的时代开始来临。

2004年,WHATWG 组织成立,致力于加速 HTML 语言的标准化进程。

2005年,苹果公司在 KHTML 引擎基础上,建立了 WebKit 引擎。

2005年,Ajax 方法(Asynchronous JavaScript and XML)正式诞生,Jesse James Garrett 发明了这个词汇。它开始流行的标志是,2月份发布的 Google Maps 项目大量采用该方法。它几乎成了新一代网站的标准做法,促成了 Web 2.0时代的来临。

2005年,Apache 基金会发布了 CouchDB 数据库。这是一个基于 JSON 格式的数据库,可以用 JavaScript 函数定义视图和索引。它在本质上有别于传统的关系型数据库,标识着 NoSQL 类型的数据库诞生。

2006年,jQuery 函数库诞生,作者为John Resig。jQuery 为操作网页 DOM 结构提供了非常强大易用的接口,成为了使用最广泛的函数库,并且让 JavaScript 语言的应用难度大大降低,推动了这种语言的流行。

2006年,微软公司发布 IE 7,标志重新开始启动浏览器的开发。

2006年,Google推出 Google Web Toolkit 项目(缩写为 GWT),提供 Java 编译成 JavaScript 的功能,开创了将其他语言转为 JavaScript 的先河。

2007年,Webkit 引擎在 iPhone 手机中得到部署。它最初基于 KDE 项目,2003年苹果公司首先采用,2005年开源。这标志着 JavaScript 语言开始能在手机中使用了,意味着有可能写出在桌面电脑和手机中都能使用的程序。

2007年,Douglas Crockford 发表了名为《JavaScript: The good parts》的演讲,次年由 O'Reilly 出版社出版。这标志着软件行业开始严肃对待 JavaScript 语言,对它的语法开始重新认识,

2008年,V8 编译器诞生。这是 Google 公司为 Chrome 浏览器而开发的,它的特点是让 JavaScript 的运行变得非常快。它提高了 JavaScript 的性能,推动了语法的改进和标准化,改变外界对 JavaScript 的不佳印象。同时,V8 是开源的,任何人想要一种快速的嵌入式脚本语言,都可以采用 V8,这拓展了 JavaScript 的应用领域。

2009年,Node.js 项目诞生,创始人为 Ryan Dahl,它标志着 JavaScript 可以用于服务器端编程,从此网站的前端和后端可以使用同一种语言开发。并且,Node.js 可以承受很大的并发流量,使得开发某些互联网大规模的实时应用变得容易。

2009年,Jeremy Ashkenas 发布了 CoffeeScript 的最初版本。CoffeeScript 可以被转换为 JavaScript 运行,但是语法要比 JavaScript 简洁。这开启了其他语言转为 JavaScript 的风潮。

2009年,PhoneGap 项目诞生,它将 HTML5 和 JavaScript 引入移动设备的应用程序开发,主要针对 iOS 和 Android 平台,使得 JavaScript 可以用于跨平台的应用程序开发。

2009,Google 发布 Chrome OS,号称是以浏览器为基础发展成的操作系统,允许直接使用 JavaScript 编写应用程序。类似的项目还有 Mozilla 的 Firefox OS。

2010年,三个重要的项目诞生,分别是 NPM、BackboneJS 和 RequireJS,标志着 JavaScript 进入模块化开发的时代。

2011年,微软公司发布 Windows 8操作系统,将 JavaScript 作为应用程序的开发语言之一,直接提供系统支持。

2011年,Google 发布了 Dart 语言,目的是为了结束 JavaScript 语言在浏览器中的垄断,提供更合理、更强大的语法和功能。Chromium浏览器有内置的 Dart 虚拟机,可以运行 Dart 程序,但 Dart 程序也可以被编译成 JavaScript 程序运行。

2011年,微软工程师Scott Hanselman提出,JavaScript 将是互联网的汇编语言。因为它无所不在,而且正在变得越来越快。其他语言的程序可以被转成 JavaScript 语言,然后在浏览器中运行。

2012年,单页面应用程序框架(single-page app framework)开始崛起,AngularJS 项目和 Ember 项目都发布了1.0版本。

2012年,微软发布 TypeScript 语言。该语言被设计成 JavaScript 的超集,这意味着所有 JavaScript 程序,都可以不经修改地在 TypeScript 中运行。同时,TypeScript 添加了很多新的语法特性,主要目的是为了开发大型程序,然后还可以被编译成 JavaScript 运行。

2012年,Mozilla 基金会提出 asm.js 规格。asm.js 是 JavaScript 的一个子集,所有符合 asm.js 的程序都可以在浏览器中运行,它的特殊之处在于语法有严格限定,可以被快速编译成性能良好的机器码。这样做的目的,是为了给其他语言提供一个编译规范,使其可以被编译成高效的 JavaScript 代码。同时,Mozilla 基金会还发起了 Emscripten 项目,目标就是提供一个跨语言的编译器,能够将 LLVM 的位代码(bitcode)转为 JavaScript 代码,在浏览器中运行。因为大部分 LLVM 位代码都是从 C / C++ 语言生成的,这意味着 C / C++ 将可以在浏览器中运行。此外,Mozilla 旗下还有 LLJS (将 JavaScript 转为 C 代码)项目和 River Trail (一个用于多核心处理器的 ECMAScript 扩展)项目。目前,可以被编译成 JavaScript 的语言列表,共有将近40种语言。

2013年,Mozilla 基金会发布手机操作系统 Firefox OS,该操作系统的整个用户界面都使用 JavaScript。

2013年,ECMA 正式推出 JSON 的国际标准,这意味着 JSON 格式已经变得与 XML 格式一样重要和正式了。

2013年5月,Facebook 发布 UI 框架库 React,引入了新的 JSX 语法,使得 UI 层可以用组件开发,同时引入了网页应用是状态机的概念。

2014年,微软推出 JavaScript 的 Windows 库 WinJS,标志微软公司全面支持 JavaScript 与 Windows 操作系统的融合。

2014年11月,由于对 Joyent 公司垄断 Node 项目、以及该项目进展缓慢的不满,一部分核心开发者离开了 Node.js,创造了 io.js 项目,这是一个更开放、更新更频繁的 Node.js 版本,很短时间内就发布到了2.0版。三个月后,Joyent 公司宣布放弃对 Node 项目的控制,将其转交给新成立的开放性质的 Node 基金会。随后,io.js 项目宣布回归 Node,两个版本将合并。

2015年3月,Facebook 公司发布了 React Native 项目,将 React 框架移植到了手机端,可以用来开发手机 App。它会将 JavaScript 代码转为 iOS 平台的 Objective-C 代码,或者 Android 平台的 Java 代码,从而为 JavaScript 语言开发高性能的原生 App 打开了一条道路。

2015年4月,Angular 框架宣布,2.0 版将基于微软公司的TypeScript语言开发,这等于为 JavaScript 语言引入了强类型。

2015年5月,Node 模块管理器 NPM 超越 CPAN,标志着 JavaScript 成为世界上软件模块最多的语言。

2015年5月,Google 公司的 Polymer 框架发布1.0版。该项目的目标是生产环境可以使用 WebComponent 组件,如果能够达到目标,Web 开发将进入一个全新的以组件为开发基础的阶段。

2015年6月,ECMA 标准化组织正式批准了 ECMAScript 6 语言标准,定名为《ECMAScript 2015 标准》。JavaScript 语言正式进入了下一个阶段,成为一种企业级的、开发大规模应用的语言。这个标准从提出到批准,历时10年,而 JavaScript 语言从诞生至今也已经20年了。

2015年6月,Mozilla 在 asm.js 的基础上发布 WebAssembly 项目。这是一种 JavaScript 引擎的中间码格式,全部都是二进制,类似于 Java 的字节码,有利于移动设备加载 JavaScript 脚本,执行速度提高了 20+ 倍。这意味着将来的软件,会发布 JavaScript 二进制包。

2016年6月,《ECMAScript 2016 标准》发布。与前一年发布的版本相比,它只增加了两个较小的特性。

2017年6月,《ECMAScript 2017 标准》发布,正式引入了 async 函数,使得异步操作的写法出现了根本的变化。

2017年11月,所有主流浏览器全部支持 WebAssembly,这意味着任何语言都可以编译成 JavaScript,在浏览器运行。


Who——谁在用JavaScript?

每一个网页开发人员——现在叫前端开发工程师了;

一部分轻量级应用的开发人员——包括移动和桌面端;

一部分的网络服务器开发人员。

简而言之:全栈!


Why——为什么要用JavaScript?

  • 操控浏览器的能力:作为浏览器内置脚本语言,为网页开发者提供操控浏览器的能力,也是唯一一种通用的浏览器脚本语言;
  • 广泛的使用领域
    • 浏览器平台化:浏览器随着HTML5的出现越来越强大,JavaScript可以有可能调用许多系统功能;
    • 服务器:Node.js项目的出现使得JavaScript可以用于开发服务器端的大型项目,使得JavaScript进行后端开发不再是一种可能性,而是真正成为了现实;
    • 数据库操作:NoSQL数据库概念诞生于JSON格式(JavaScript Object Notation)的基础上,允许JavaScript直接进行操作,甚至如PostgreSQL这样的开源数据库,支持JavaScript直接作为操作语言,部分取代了SQL查询语言;
    • 移动平台开发:越来越多的项目开始将JavaScript作为开发语言,如PhoneGap,是将其和HTML5打包在一个容器里面,使得写好的应用可以同时在iOS和安卓上面运行;而React Native则是将JavaScript写好的组件,编译成原生组件使其可以运行并具备优秀的性能;
    • 内嵌脚本语言:越来越多应用程序开始将JavaScript作为内嵌脚本语言了,譬如Adobe Acrobat、GNOME等等;
    • 跨平台的桌面应用程序:如Chromium OS、Windows 10等已经直接支持JavaScript编写应用程序;而Mozilla的Firefox OS App项目、Google的Chrome App项目、GitHub的Electron项目以及TideSDK项目,都可以用来编写桌面程序而无需浏览器支持;
  • 易学性
    • 学习环境:只要有浏览器,就可以运行JavaScript;只要有文本编辑器,就能编写JavaScript——几乎所有电脑都原生提供了JavaScript学习环境,甚至不需要安装复杂的IDE和编译器;
    • 简单:相比其他脚本语言(如Ruby或者Python),它的语法相对更简单,且语法特性不算多,完全可以指用简单命令完成大部分操作;
    • 与主流语言的相似:其语法和C/C++或者Java很相似,所以一旦有过相关学习经历,JavaScript的入门会很容易

但JavaScript有其特殊的复杂性:

涉及大量的外部API:一旦需要使用该语言完成任务,就难免涉及到大量的外部组件配合,而其数量的庞大导致学习成本的直线上升;
JavaScript的语言设计有些缺陷:有些地方极其不合理,还有些会出现非常怪异的运行结果,学习的很大一部分是用来避免“踩坑”——也因此,出现了很多基于JavaScript的新语言如:CoffeeScript、TypeScript还有Dart,无形中也增加了学习成本;
  • 性能强大
    • 语法灵活,表达力强:支持类似C的过程式编程,也支持函数式编程,可以用来写并发处理(concurrent),尤其适用异步编程;其所有值都是对象,为程序员提供了灵活性和便利性;
    • 支持编译运行:虽然JavaScript是一种解释性语言,但在现代浏览器中它都是编译后运行,会被高度优化,执行效率可以接近二进制程序,且其引擎仍然在高速发展,性能将会越来越好;另外还有WebAssembly格式,全部都是二进制代码,其他语言通过编程成该格式,就可以在浏览器里面运行;
    • 事件驱动和非阻塞式运行:可以采用事件驱动(Event-driven)以及非阻塞式(Non-blocking)设计,在服务器端适合高并发环境;
  • 开放性:这门语言不属于任何公司或者个人,不存在版权和专利的问题;其标准是ISO国标,有TC39委员会制定,所有的运作和讨论都是开放的,且记录都会对外公布;
  • 社区支持和就业机会:全球都在使用JavaScript,极大的社区、广泛的文献和书籍、丰富的代码资源,绝大部分功能都有多个开源库可供使用;就业也不难。

How——如何使用JavaScript?

这个就是后面需要详细了解的了,先从基本语法开始!

评论

此博客中的热门博文

Node.js从零开始——事件、系统和流

毕竟不是一个真正的教程,这里主要还是以普及和介绍为主,所以这一部分就是 Node.js 的其他部分介绍了,主要也就是事件触发、操作系统以及流的知识。 1 事件触发器 因为我们之前在浏览器中使用 JavaScript ,所以知道 JS 通过事件处理了许多用户的交互:鼠标的单击、键盘按钮的按下、对鼠标移动的反应等等。 在后端, Node.js 也提供了使用 events 模块 构建类似系统的选项。 具体上,此模块提供了 EventEmitter 类,用于处理事件。 使用以下代码进行初始化: const EventEmitter = require ( 'events' ); const eventEmitter = new EventEmitter (); 该对象公开了 on 和 emit 方法: emit 用于触发事件 on 用于添加回调函数(会在事件被触发时执行) 例如,创建 start 事件,并提供一个示例,通过记录到控制台进行交互: eventEmitter . on ( 'start' , () => { console . log ( '开始' ); }); 当运行以下代码时: eventEmitter . emit ( 'start' ); 事件处理函数会被触发,且获得控制台日志。 可以通过将参数作为额外参数传给 emit() 来将参数传给事件处理程序: eventEmitter . on ( 'start' , number => { console . log ( `开始 ${ number } ` ); }); eventEmitter . emit ( 'start' , 23 ); 多个参数: eventEmitter . on ( 'start' , ( start , end ) => { console . log ( `从 ${ start } 到 ${ end } ` ); }); eventEmitter . emit ( 'start' ,

Node.js从零开始——HTTP 服务器

其实 Node.js 最初的目的,就是实现一个完全可以由 JavaScript 来进行开发的服务器端,所以归根到底,它的后端能力之一就是实现一个 HTTP 服务器,这里我们来看看它。 1 搭建 HTTP 服务器 其实前面我们已经看过了一个例子,不过这里再来看一个 HTTP web 服务器的例子: const http = require ( 'http' ); const port = 3000 ; const server = http . createServer (( req , res ) => { res . statusCode = 200 ; res . setHeader ( 'Content-Type' , 'text/plain' ); res . end ( '你好世界\n' ); }) server . listen ( port , () => { console . log ( `服务器运行在 http:// ${ hostname } : ${ port } /` ); }); 简要分析一下: 这里引入了 ref=" http:// nodejs.cn/api/http.html ">http 模块:使用该模块来创建 HTTP 服务器 服务器被设置为在指定的 3000 端口上进行监听, 当服务器就绪时,则 listen 回调函数会被调用 传入的回调函数会在每次接收到请求时被执行, 每当接收到新的请求时, "http://nodejs.cn/api/http.html#http_event_request">request 事件 会被调用,并提供两个对象:一个请求( http.IncomingMessage 对象)和一个响应( http.ServerResponse 对象) request 提供了请求的详细信息, 通过它可以访问请求头和请求的数据, response 用于构造要返回给客户端的数据;在此示例中: res . statusCode = 200 ; 设置 status

Web API从零开始——SVG

SVG 是我基本没有用过的知识块,所以这里也是边分享边学习,尽量在我自己理解的基础上来分享。 1 概念 SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector Graphics);其他图像格式都是基于像素处理的, SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。 SVG 文件可以直接插入网页,成为 DOM 的一部分,然后用 JavaScript 和 CSS 进行操作。 上面是 SVG 代码直接插入网页的例子。 SVG 代码也可以写在一个独立文件中,然后用 、 、 、 等标签插入网页: < img src = "circle.svg" > < object id = "object" data = "circle.svg" type = "image/svg+xml" ></</span> object > < embed id = "embed" src = "icon.svg" type = "image/svg+xml" > < iframe id = "iframe" src = "icon.svg" ></</span> iframe > CSS 也可以使用 SVG 文件: . logo { background : url ( icon.svg ); } SVG 文件还可以转为 BASE64 编码,然后作为 Data URI 写入网页: < img src = "data:image/svg+xml;base64,[data]" > 2 语法 2.1 标签 我们可以把 SVG 代码都放在顶层标签 之中,下面是一个例子: < svg width = "100%" height = "100%" >