什么是 JAVASCRIPT? | 历史与核心概念总结

前言

做为程序员,技术的落实与巩固是必要的,所以想到写个系列,名为 why what or how 每篇文章试图解释清楚一个问题。javascript

此次的 why what or how 主题:什么是 JavaScripthtml

释义

JavaScript - 一种解释性脚本语言前端

解释性脚本语言:一类不具有开发操做系统的能力,而是只用来编写控制其余大型应用程序的“脚本”,但其内容的的执行不须要提早编译的语言。一般做为别的程序的输入。java

JavaScript,是一种用于描述网页逻辑,处理网页业务的解释性脚本语言,纯文本,其内容做为浏览器的输入,浏览器负责解释编译运行其内容。node

目前 JavaScript 也成功被应用于服务端,服务端的 JavaScript 用于描述业务逻辑,其内容做为 node 的输入, node 负责解释编译运行其内容。webpack

JavaScript 是伴随着浏览器出现的一门特殊的语言,特殊在哪呢? JavaScript 是惟一一门全部浏览器都支持的脚本语言,也就说若是你的 WEB 程序想在客户端作点事,就必定会用到 JavaScript 。别看如今 JavaScript 煊赫一时,但它最开始出现却仅为了验证表单。git

历史

  • 1990 - 1994,虽然各类浏览器开始出现,但浏览器仅用做数据展现,并无客户端逻辑存在。
  • 1994Netscape 公司计划实现一种浏览器脚本语言进行一些简单的表单验证。
  • 1995Netscape 公司雇佣了程序员 Brendan Eich 开发这种网页脚本语言。
  • 1995.5Brendan Eich 用了 10 天,设计完成了这种语言的初版。取名为:Mocha
  • 1995.9Netscape 公司将该语言更名为 LiveScript
  • 1995.12NetscapeSun 公司联合发布了 JavaScript 语言。
  • 1996.3Navigator 2.0 浏览器正式内置了 JavaScript 脚本语言。
  • 1996.8,微软发布 Internet Explorer 3.0 ,同时发布了 JScript ,该语言模仿同年发布的 JavaScript
  • 1996.11Netscape 公司在浏览器对抗中没落,将 JavaScript 提交给国际标准化组织 ECMA ,但愿 JavaScript 可以成为国际标准,以此抵抗微软。
  • 1997.7ECMAScript 1.0 发布。ECMAScript 是一种标准,而 JavaScript 是该标准的一种实现。
  • 1997.10Internet Explorer 4.0 发布,其中的 JScript 基于 ECMAScript 1.0 实现。
  • 1999IE 5 部署了 XMLHttpRequest 接口,容许 JavaScript 发出 HTTP 请求,为后来 Ajax 应用创造了条件。
  • 1999.12ECMAScript 3.0 版发布,获得了浏览器厂商的普遍支持。
  • 2005Ajax 方法(Asynchronous JavaScript and XML)正式诞生,Google Maps 项目大量采用该方法,促成了 Web 2.0 时代的来临。
  • 2006jQuery 函数库诞生,做者为 John ResigjQuery 统一了不一样浏览器操做 DOM 的不一样实现,被普遍使用,极大下降了 JavaScript 语言的应用成本,推进了语言的流行。
  • 2007.10ECMAScript 4.0 草案发布,对 3.0 版作了大幅升级,但因为改动幅度过大,遭到了各大浏览器厂商的反对。
  • 2008.7,各大厂商对 ECMAScript 4.0 版本的开发分歧太大,ECMA 开会决定,停止 ECMAScript 4.0 的开发,对其中一些已经改善的部分发布为 ECMAScript 3.1。不久以后就更名为 ECMAScript 5
  • 2008,由 google 开发的 V8 编译器诞生。极大提升了 JavaScript 的性能,为以后 node 的诞生打下了基础。
  • 2009Node.js 项目诞生,创始人为 Ryan DahlJavaScript 正式应用于服务端,以其极高的并发进入人们的视野。
  • 2009.12ECMAScript 5.0 正式发布。同时将标准的设想定名为 JavaScript.nextJavaScript.next.next 两类。
  • 2010NPMRequireJS 出现,标准着 JavaScript 进入模块化。
  • 2011.6ECMAscript 5.1 发布,而且成为 ISO 国际标准(ISO/IEC 16262:2011)。
  • 2012,单页面应用程序框架(single-page app framework)开始崛起,AngularJS 项目出现。
  • 2012,全部主要浏览器都支持 ECMAScript 5.1 的所有功能。
  • 2012,微软发布 TypeScript 语言。为 JavaScript 添加了类型系统。
  • 2013ECMA 正式推出 JSON 的国际标准,这意味着 JSON 格式已经变得与 XML 格式同样重要和正式了。
  • 2013.2Grunt.js 前端构建化工具发布,前端进入自动化开发阶段。
  • 2013.5Facebook 发布 UI 框架库 React
  • 2013.8, Gulp.js 3.0 前端构建工具发布,js 自动化开发变得简单起来。
  • 2014,尤雨溪发布 VUE 项目。
  • 2015.3Facebook 公司发布了 React Native 项目,将 React 框架移植到了手机端,用来开发手机 App
  • 2015.3babel 5.0 发布,ES6 代码正式引用于开发,而不须要考虑兼容问题。
  • 2015.6ECMAScript 6 正式发布,而且改名为 ECMAScript 2015
  • 2015.6Mozillaasm.js 的基础上发布 WebAssembly 项目。
  • 2015.9Webpack 1.0 发布,模块系统获得普遍的使用。
  • 2016.6ECMAScript 2016(ES7) 标准发布。
  • 2017.6ECMAScript 2017(ES8) 标准发布,引入了 async 函数,使得异步操做的写法出现了根本的变化。
  • 2017.11,全部主流浏览器所有支持 WebAssembly,这意味着任何语言均可以编译成 JavaScript,在浏览器中运行。
  • 2018.6ECMAScript 2018(ES9) 标准发布。
  • 2019.6ECMAScript 2019(ES10) 标准发布。
  • ...

纵观发展历史,很容易就能发现其中几个关键点的出现,极大的促进了 JavaScript 的发展。程序员

  1. XMLHttpRequest 接口的出现,JavaScript 开始有了与服务器沟通的能力,诞生了 ajax ,同时也促进了 RestFul API 的发展。
  2. jQuery 函数库诞生,极大的下降了网页开发成本。
  3. V8 的出现,下降了 JavaScript 消耗的资源,加快了编译速度,复杂的 JavaScript 程序开始出现。
  4. Node.js 项目诞生,JavaScript 开始应用在服务端。
  5. NPMRequireJS 出现,JavaScript 正式进入模块化。
  6. Grunt Gulp Webpack 这些自动化构建工具的出现,极大的下降了开发成本,统一了各类内容的构建方式。
  7. Babel 的出现完全让前端程序员放开了手脚,毫无顾忌的使用 ES6 而无须担忧平台的兼容性问题。
  8. Angular React Vue 的出现了,进一步下降了网页开发成本,单页应用开始出现。
  9. ECMAScript 6 标准的公布以及实现,弥补了 JavaScript 的语言缺陷,JavaScript 更好用了。

直到目前,JavaScript 已经成为了 GitHub 上最热门的语言,从前端到后端在到桌面,都有 JavaScript 的身影,但 JavaScript 语言自己的内容并很少,那么 JavaScript 语言自己都有哪些内容?es6

语法 & 标准库

JavaScript 的语法,这里仅罗列一些概念,具体的能够查看JavaScript开发文档web

数据类型

JavaScript 中全部的数据都有类型,以下所示:

类型 定义 示例 含义
null 空值 let a = null 一个特殊的空值
undefined 该值未定义 let a 该值声明了但未定义
Number 数值 let a = 1 包括整数、浮点数、科学计数等全部数字
String 字符串 let a = '1' 单个字符也是字符串
Boolean 布尔值 let a = true 仅有 truefalse ,表明真假
Symbol 符号 let a = Symbol(42) 一类永远都不会相同的值,经常使用做对象的 key
Object 对象 let a = { a: 1 } 一类拥有多个键值对的数据

JavaScript 中数据类型除了能够按照上述的分类方式,还能够简单的分为:基本数据类型(除了 Object 的其余类型)和引用类型(Object),这和变量的存储方式有关,这里不过于深刻,但 JavaScript 数据是如何存储的?以后会写,请持续关注~

运算符 & 流程 & 声明

  • 运算符
  1. 算术 + - * / ** % ++ --
  2. 比较 > >= < <= == != === !==
  3. 布尔运算 ! || && ?:
  4. 二进制运算 | & ~ ^ << >> >>>

在进行算术、比较、布尔运算时,会出现类型转换,会有一些怪异的表现,那么 JavaScript 是如何进行类型转换的?以后会写,请持续关注~

  • 流程
  1. for(let i = 0; i < n; i++){ ... }
  2. for(let key in obj){ ... }
  3. for(let value of array){ ... }
  4. while(true){ ... }
  5. do{ ... }while(true)
  6. if(true){ ... }else if(true){ ... }else{ ... }
  7. switch(a){ case() ... }

和大多数的语言同样,都有相似的流程语句。仅须要注意 for...of 循环便可。

  • 声明
  1. 常量 - const
  2. 变量 - let or var(不建议使用)
  3. 同步函数 - function
  4. 异步函数 - async function
  5. Generator 函数 - function*

ok,JavaScript 的基础知识就差很少也就这些,这里仅是罗列,并不过多的深刻,有兴趣或是不了解的能够在JavaScript 教程,进行学习。

标准库

何为标准库?

在了解 JavaScript 发展史后,咱们都知道,EcmaScriptJavaScript 语言实现的标准,标准除了规定基本的语法外,还定义了一些列 JavaScript 执行环境应该有的对象或是函数,这些与语法无关的其余内容,就被称为标准库。标准库主要包含如下内容(一些已废弃或不推荐使用的就不罗列了):

  • 全局函数
  1. eval()
  2. isFinite()
  3. isNaN()
  4. parseFloat()
  5. parseInt()
  6. decodeURI()
  7. decodeURIComponent()
  8. encodeURI()
  9. encodeURIComponent()
  10. ...
  • 全局对象
  1. Number
  2. String
  3. Boolean
  4. Symbol
  5. Object
  6. Function
  7. Error
  8. Math
  9. Date
  10. RegExp
  11. Array
  12. Map
  13. Set
  14. JSON
  15. Promise
  16. Generator
  17. GeneratorFunction
  18. AsyncFunction
  19. Proxy
  20. Reflect
  21. WebAssembly
  22. ...

具体内容能够点击查看,这里仅是罗列出一些经常使用的函数以及对象,一些对象若是不操做视频、音频、图像等内容也用不到,这里就不写了。

宿主环境

JavaScript 做为一门解释性脚本语言,其内容只能做为别的程序的输入,而这个别的程序,就是宿主环境。那么宿主环境为 JavaScript 提供了什么呢?

  1. 语法支持,宿主环境最重要的就是须要知道 JavaScript 文本内容到底干了什么。
  2. 标准库支持, JavaScript 代码会使用 EcmaScript 所规定的标准库,所以必须实现。
  3. 环境实现,不一样的宿主环境为了实现不一样的功能,会提供了不一样的实现,好比浏览器上的 BOMDOMnode 上的 fs path 等模块。

浏览器

做为 JavaScript 最重要的宿主环境,JavaScript 携手已经走过了将近 20 年,浏览器由于 JavaScript 而大放异彩,JavaScript 也由于浏览器露出锋芒。

浏览器为 JavaScript 提供语法和标准库支持外,还实现了两大类 APIDOM(Document Object Model)BOM(Browser Object Model)

DOM

DOM(Document Object Model) - 文档对象模型。

不一样于 EcmaScriptDOM 的规范化组织为 W3C,也就是说 DOM 实际上是 HTML 标准化的一部分,所以 HTML5 最新标准涵盖一些 DOM API 是正常的。查看 W3C DOM 的最新规范Document Object Model

那么何为文档对象模型?

咱们都知道 HTML 能够简单的理解为标签的嵌套,嵌套的标签造成了树状结构。DOM 将该树状结构提炼成了 JavaScript 中的一个对象 document 经过该对象,JavaScript 就拥有了操做文档中某个标签的能力,从而改变标签的结构,样式,内容监听标签的事件等等。

DOM 涉及的 API 不少,但其 API 都有一个特色,以 标签 打头,好比 body.addEventListener document.getElementsByTagName 等等,能够经过如下内容进行学习:

BOM

BOM(Browser Object Model) - 浏览器对象模型。

BOM 其实到目前尚未一个规范化组织来制定标准,所以各个浏览器的实现彻底按照本身的标准来,MDN 上也没有专门的介绍页面,说实话有点惨,但虽然没有标准,各个浏览器实现的 API 却基本相同。

BOM 能够简单的理解为浏览器实现了一套 API 使得 JavaScript 能与浏览器进行交互。相关的 API 所有放在 window 对象下。

window 对象主要包含如下对象:

  • document - 对 DOM 的引用
  • frames - 对当前页面中的 iframe 的引用
  • history - 浏览器浏览记录相关 API
  • location - 浏览器地址相关 API
  • localStorage - 本地数据存储
  • sessionStorage - 会话级别的数据存储
  • navigator - 浏览器导航信息相关 API
  • screen - 屏幕信息

Node

Node 做为 JavaScript 服务端的宿主环境,除了提供了语法和标准库的支持外,还实现了一系列的模块,每一个模块都有具体的做用,具体能够查看Node 官方文档

其实异步的编程模式是不容易被应用在服务端的,或者说服务端更偏向于同步模式。

服务端的极大多数代码都须要运行在一个同步的环境下,好比数据库的查找,文件的读取,请求结果的读取等等,若是在都将逻辑写在异步的回调中,代码将变得的难以解读,并且代码编写也会变得复杂起来。好比须要安装顺序读取 10 次外部接口的数据,同步模式下,只要按照顺序从前日后写便可,而异步模式只能嵌套加嵌套(或者 Promise.then )不只写出来的代码难以读懂,代码也难以维护。

可是为何 Node 仍是大热呢?我的感受有如下几个缘由:

  1. 前端自动化打包的出现。
  2. 虽然异步模式不适合服务端,但却极其符合请求的过程:请求触发任务。
  3. 主线程仅分发任务,而不须要处理读取文件,数据库等耗时逻辑,不会致使程序堵塞,并发量能够达到很高。
  4. 其数据结构与前端须要的结构一致(原生支持 JSON)。
  5. 语法灵活,直接操做数据,屏蔽或是添加一些字段,处理一些前置逻辑。
  6. 简单,包括环境搭建简单,启动简单程,序编写简单,还有 NPM 上各类库。
  7. ES8 AsyncFunction 异步函数的出现,将异步模式的写法向同步写法趋近。代码编写变得简单起来。
  8. 前端人直接上手?

对于第 8 点,我持中立态度。大前端的概念层出不穷,我想你们须要冷静冷静,不妨上手写个 Node 程序,感觉下前端异步编程是否真正的适合服务端?还有服务端虽然环境统一,但涉及的概念极多,虽然可能在本身写的小项目中并不会涉及,可是真正使用倒是会用到的,因此对于 Node 能作什么,个人理解以下:

  1. 做为前端开发的自动化工具,webpack gulp 等,语法一致,都能看懂,无非增长了一些文件读取,字符串解析。
  2. 爬虫,抓取一些本身敢兴趣的东西。对于本身的小程序,放开了手作,数据量不大,怎么整都行。
  3. 数据预处理,在大型项目中,做为请求中转站的存在,返回更加适合前端的数据,或是将前端过来的数据更加适合后端程序,也就是数据映射。在日后交给专业的后端大佬们便可,咱们就无论了。

Electron

Electron 做为一个跨平台的 GUI 工具,使用 ChromiumNode 构建,实现了使用 JavaScript 开发桌面应用程序,也能够算是一个 JavaScript 的宿主环境,但其实至关于实现了一个浏览器, JavaScript 也被分为两部分,这两部分的宿主环境分别为 Node 和浏览器。具体能够查看Electron 官网

Event Loop

无论 JavaScript 程序的运行在 Node 端仍是运做在浏览器端,都是以单线程的形式运行在宿主环境下,那么 JavaScript 是如何处理多任务的呢?

异步 + Event Loop

简单描述下:JavaScript 会调用宿主环境提供的 API 处理不一样的任务(这些任务运行在别的线程)并设置这些任务的回调,当这些任务完成时,会在事件队列中放入任务对应的回调,而 JavaScript 主线程会不断的去处理事件队列中的任务,这个过程就被称为 Event Loop

因为这个过程并不在 ECMAScript 所规定的规范中,所以不一样的宿主环境实现是有区别的,具体能够查看我以前写的文章:

语言特色

每种语言都有本身的特色,JavaScript 也不例外,下面就谈谈 JavaScript 使人着迷,或是苦恼的地方。

数据存储

每种编程语言都须要处理数据和变量的关系,JavaScript 也不例外。但做为脚本,它须要运行在一个特定的宿主环境,那么这个宿主环境储存了 JavaScript 运行时产生的全部数据,又因为闭包的存在,使得这些数据能改被各类各样的变量所引用,而 JavaScript 中变量又是无类型的,各类奇奇怪怪的赋值方式,会致使各类奇奇怪怪的结果,这能够定义为复杂,但也能够定义为灵活。熟悉它你能够畅游在 JavaScript 的世界中,笑谈程序;而霸王硬上弓,却会陷入无尽的 bug 中。

那么 JavaScript 中数据是如何存储的?请持续关注 ~ 争取说清楚。

做用域 & 闭包

做用域你们都很熟悉,由双大括号产生(ES6+),内层变量能够引用到外层变量,而外层变量却对内层变量无能为力。但函数的闭包却打破了这层限制,可让外部程序有了改变或获取内部变量的能力,同时因为数据存储的缘由,外部程序在必定状况下甚至对内部变量能够随心所欲。

那么 到底何为做用域?闭包在这里扮演的什么角色?请持续关注 ~

函数

JavaScript 是一种函数先行的语言,表如今代码上为:能够直接定义 function 或是直接将 function 赋值给某个变量。

函数,何为函数?函数能够理解为一种行为,一段过程,或是一个任务,而这些都有一个显著的特色,有起始点和终点。对应到函数上即为入参和返回值,在面向对象编程被大肆宣传的状况下,函数式编程却在发挥着独特的魅力,以其天然清晰简洁的编程方式,吸引着众人的眼光。

函数式编程式一个极大的内容,什么是函数式编程光解释是没有用的,只有本身亲自上手体验一把才能感觉到它的魅力。

有兴趣的朋友能够翻阅JS 函数式编程指南

原型链

前面说到,JavaScript 是一种函数先行的语言,那么 JavaScript 就不能面向对象了?错!ES6 class 语法的出现,标志着 JavaScript 彻底是可以面向对象的。查看通过 babel 转码后的 ES5 兼容代码,能够清楚的知道 class 仅仅只是一个语法糖,否则如何进行转码呢?而面向对象实现的关键是 JavaScript 的另一个特色:原型链(prototype)。

那么 何为原型链(prototype)?原型又是什么?请持续关注 ~ 争取说清楚。

this

谈到 this 相信大部分面向对象编程语言的 coder 都很熟悉,经常出如今对象所属的方法中,JavaScript 表现出来的行为和这些语言一致,但其本质倒是极大的不一样,由于在每个函数下都有 this 的存在,那么 this 究竟是什么?其所表明的又是什么内容?这和 JavaScript 的数据存储有点关系,所以在不弄懂数据存储前,this 每每难以预测。

this 究竟是如何取值的,在 JavaScript 中数据是如何存储的?中会有提到,请持续关注 ~

箭头函数

已经说了函数,为什么还要单独写个箭头函数?相信你们对于箭头函数的理解仅仅在简化的正常函数上,但箭头函数和用 function 声明的函数是有区别的,试想一想,在 VUE 文档中是否有这么一句话:XXX 只接受 function。这个 function 不表明箭头函数。那么箭头函数究竟是什么?和普通函数又有什么区别?什么状况下该使用箭头函数呢?

请看以后的文章:什么是箭头函数?

其余

JavaScript 语言的特色还有不少,ES6 ~ ES10 陆陆续续更新很多内容,包括 Promise Proxy Iterator Generator async 等不少内容,这些都是语言上的更新,具体的使用查看文档便可。

ECMAScript 6 入门

固然也推荐推荐以前在看《ECMAScript 6 入门》时,写下的笔记ecmascript6。欢迎查阅~~

模块化

JavaScript 的模块化由 RequireJs(AMD)开启,终结于 ES6(Module)规范,中间经历了 SeaJS(CMD)Node(CommonJS)。目前经常使用的为 CommonJS(Node)Module(ES6 + Babel),其余的咱们能够略过。

CommonJS

CommonJSNode 端的模块系统,内置 3 个变量 require exportsmodule。经过 require 引入模块,exports 对外导出,module 保存该模块的信息。以下所示

'use strict';

var x = 5;
function addx (value){
    console.log( x + value );
}

exports.addx = addx;
复制代码

相信你们都知道,导出还有一种写法

module.exports.addx = addx;
// or
module.exports = { addx };
复制代码

其实只要知道 module.exports === exports // true,那么一切就解释的通了,exports 仅为 module.exports 的一个引用,可是如下写法是有问题的

exports = { addx };
复制代码

出现问题的缘由是 exports 只是一个引用,若是从新赋值的话会致使该变量引用到另外一个数据上,这样的结果就是 module.exports === exports // false,而模块的信息是以 module 为标准的,所以就变成了无导出。那若是究其缘由到底为何会发生引用变化,能够查看 JavaScript 中数据是如何存储的?虽然还没写,但确定会写的。

Module

ModuleES6 推出的模块化规范,目的在于统一各类不一样的规范,由 import 导入 export 导出。以下所示

import { stat, exists, readFile } from 'fs';

export const a = '100'; 
// or
const a = '100';
export {
    a
}
复制代码

常见的导入语句有

  1. import { xxx } from 'a'; - 从 a 中导出 xxx 的属性或方法,数据由 aexport 导出
  2. import { xxx as yyy } from 'a'; - 从 a 中导出 xxx 的属性或方法并重命名为 yyy,数据由 aexport 导出
  3. import xxx from 'a'; - 从 a 中导出默认值,并赋值为 xxx,数据由 aexport default 导出

常见的导出语句有

  1. export const a = 1; - 导出一个常量,名字为 a 值为 1
  2. export { a }; - 导出名字为 a 的属性或方法,其值为做用域中变量 a 的值
  3. export { a : b }; - 导出名字为 a 的属性或方法,其值为做用域中变量 b 的值,其上为 export { a : a } 的缩写
  4. export default a; - 导出默认值,其值为做用域中变量 a 的值
  5. export default 1; - 导出默认值,其值为 1

常见的错误导出语句

  1. export a;
  2. export default const a = 1;

以上是常见的错误导出语句,如何避免?只要记住如下规则便可:

  1. export 导出的值,必需要有名字,constlet 这些声明语句规定了该值的名字,{a: b},也规定了名字。
  2. export default 仅导出值,所以不须要有特殊的方式规定名字。

总结

惯例,问几个问题

  1. 什么是解释性脚本语言?
  2. EMCAScriptJavaScript 是什么关系?
  3. JavaScript 都有哪些数据类型?
  4. JavaScript 的流程控制语句与运算符都有哪些?
  5. JavaScript 的语言特色是什么?
  6. JavaScript 模块是如何定义的?

参考

最后的最后

该系列全部问题由 minimo 提出,爱你哟~~~

相关文章
相关标签/搜索