JavaScript 是我在下一阶段工作中要大量用到的语言,既用于前端也用于后端开发(写到这里可能有读者已经知道我的下一份工作的技术栈大致是什么了)。因此,手动翻译JS的维基百科页面以拓展自己对这个语言的宽泛的知识。对,我知道JS的维基百科页面已有中文版,所以本翻译不注重本土化(如添加中国大陆香港台湾地区的JavaScript发展情况),翻译也着重于该语言的机制和语法特性,对发展历史这类话题则采取简略翻译。翻译参考版本为2018年5月29日读取的 https://en.wikipedia.org/wiki/JavaScript 英文人名、地名、公司名等不刻意翻译,谢谢。
以下为翻译正文
JavaScript(JS)是一种高级解释执行的语言。该语言也具备动态、弱类型、基于原型(prototype-based)和多范式等特征。
JS和HTML与CSS一道共同组成了网页的核心技术。JS使得交互式网页成为了可能。如今,绝大多数的网页浏览器都具有专门的JS引擎来执行JS。
作为一个多范式的语言,JS支持事件导向、函数式、声明式(包括面向对象和基于原型)的编程风格。它有相应的API来处理文本、数组、日期、正则表达式以及对文件对象模型(DOM)的基本操作。但是,该语言本身不具备处理IO(输入输出)操作的能力。这里的IO操作指的是网络、数据库读写、图形处理等IO。JS能否处理以及如何处理IO是取决于它所嵌入的主机环境。比如,Node.js不是一门语言,而是JavaScript的一个运行环境。
起初,JavaScript仅用于客户端如网页浏览器,但后来它也被用到网站服务器端、数据库,甚至一些文本处理工具以及PDF软件里等等。
最后,老生常谈下,JavaScript跟Java是两种不同的编程语言,尽管他们的名字中都有“Java”这个字眼。
历史
JavaScript最早由网景公司(Netscape)于1995年开发出来。它开发出后不久网景公司就也做了它的服务器端版本,但估计不流行。它开始较为流行的服务器端实现是2009年出现的Node.js。
在1995年到2017年间,比较值得书写的历史有1996年微软公司开发出的VBScript和JScript,其中的JScript就是反向编程JavaScript而实现的。再者就是这12年间JavaScript的一系列标准化过程。对于这段历史,由于篇幅,我就不翻译了,推荐阅读黄玄先生的ES5, ES6, ES2016, ES.Next: JavaScript 的版本是怎么回事?
主要时间轴是:
2009年 ECMAScript 5发布
2015年 ECMAScript 6(ES6)发布
2016年 ECMAScript 7(ES7)发布
2017年 ECMAScript 2017(ES8)发布
ECMAScript:对JavaScript语言的标准的称谓。它是由 ECMA International 这个机构进行标准化的。 还有,2015年以后的ESx版本的发布年份其实就是
x-1+2010
的值
商标
“JavaScript”是甲骨文公司的一个注册商标。该商标许可给了当年的网景公司和如今的一些机构如Mozilla基金会使用。
香草JavaScript
“Vanilla JavaScript”这个术语是指纯粹的不添加任何外在框架或是包的JavaScript。它跟俗称的“Plain JavaScript Code”等价。
特征
以下特征皆服从ECMAScript的实现,除了一些特别指出的。
全面的支持
当今所有浏览器都有内置的JS解释器。
命令式与结构
JS支持大部分的来自结构化语言C语言的语法,比如语句、while循环、switch语句、do while 循环等等。一个特例是作用域。JS起初只有用var定义的函数作用域,后来ES6增加了关键字let和const来定义块作用域(block scoping),这意味着现在的JS(ES6及以后)可以定义函数作用域和块作用域了。
与C语言类似,JS区分表达式(expressions)和语句(statements)。一个语法上的区别是C语言一定要用分号作为语句的结尾而JS中分号可以省略。
动态
类型
与诸多脚本语言类似,JS使用动态类型。JS的一个变量的类型是由它的取值决定的。
运行时求值
JS包含一个叫eval
的函数可用于在运行时计算一个由字符串提供的语句的值。注:不过eval函数很少且不鼓励使用。
基于原型(面向对象)
JS语言几乎是完全基于对象的。在JS中,一个对象就是一个拥有原型的关联型数组(associative array)。对象属性的键是string类型,且有两种方法来定义对象属性的键名称:点标记法(obj.x = 10
)或者中括号标记法(obj['x'] = 10
)。一个属性可以在运行时被加入、回弹(rebound)或者删除。一个对象中的大部分属性(也包括这个对象的原型继承链上的所有属性)都可以用for...in
循环来进行枚举。
JS也有小部分的内置对象,包括Function
和Date
。
原型(Prototypes)
JS是用原型来实现继承,其他许多面向对象的语言(比如Java)使用类来实现继承。当然,在JS中我们可以用原型来实现许多基于类继承的语言的特性。
作为构造器的函数(Functions as object constructors)
函数可以用作构造器,也可以按它本身的传统功用做方法。在函数调用前加new
关键字可以生成一个原型的实例,并从构造器继承原型的属性与方法(这里说的属性也包括Object这个原型的属性)。ECMAScript 5标准提供Object.create
这个方法。该方法允许显式地生成一个实例而不必自动继承Object
这个所有对象的总的原型。此外,构造器的原型的属性决定了用于作新对象的内置原型的对象(这句话有点绕,英文是 The constructor’s prototype property determines the object used for the new object’s internal prototype.)。我们可以通过修改用作构造器的函数的原型来添加方法。JS的内置构造器,比如Array或者Object,也提供原型用于修改。下面是重点,敲黑板:尽管我们可以修改Object
这个原型,但修改Object
原型的行为会被认为是糟糕的编程实践,因为我们编写JS代码的时候默认Object
这个原型是不变的。
作为方法的函数(Functions as methods)
不同于许多面向对象语言,JS并不区分函数和方法之间的定义区别。然而,这个区别在调用函数的时候还是会凸显出来。这个区别就是:当一个函数作为一个对象的方法被调用时,这个函数的局部的this
关键字就会被绑定到这次调用中的那个涉及到的对象(英语原句: when a function is called as a method of an object, the function’s local this
keyword is bound to that object for that invocation.)。注:这个部分提到了ECMAScript 5中容易让程序员出错的this
关键字,ES6对this
的机制做了一些改良。
函数式
一个函数就是第一类(first-class)。一个函数也被认为是一个对象。因此,一个函数可以带属性和方法,比如.call()
和.bind()
。内嵌函数(nested function)是一种 函数被定义在另一函数体内部的函数。当外函数(outer function)被调用时,内嵌函数就会被生成。此外,每个内嵌函数都形成词汇上的闭包(lexical closure):外函数词汇上的域(lexical scope,包括任一个常数、局部变量或是参数值)成为每一个内函数对象的内部状态的一部分,即便当外函数的执行已经完成了也是如此。JS也支持匿名函数。
今天先翻译到这里 2018/06/02 4:34pm
授权式(Delegative)
其它琐碎内容
特定供应商添加的扩展
语法
简单例子
高级例子
网页上的运用
代码举例
考虑兼容性
安全性
跨域的易受攻击问题
客户端的信任问题
开发者的信任问题
浏览器和插件代码错误
沙盒实现中的错误
硬件的易受攻击问题
在网页之外的应用
嵌入式脚本语言
脚本语言的引擎
应用程序平台
开发工具
给开发者的基准工具
版本历史
相关语言与技术
作为中间介质语言使用
JavaScript与Java
WebAssembly
版权声明:以上内容为代码笔记哥(Coding Bro)翻译。转载请添加这句话以及原文链接starwavelin.com/2018/05/29/js-wiki/