新闻组和邮件列表里、在计算机科学实验室里、在各大陆之间,流传着一个神秘的故事,那是关于 Perl 与动态网站之间的不得不说的往事。 -- Michael Stevenson
本文导航
-CGI 脚本和信息软件 …… 11%
-题外话 …… 26%
-回到 Perl HTTPD …… 54%
-历史展望 …… 87%
编译自: https://opensource.com/life/16/11/perl-and-birth-dynamic-web作者: Michael Stevenson
译者: wcnnbdk1
在新闻组和邮件列表里、在计算机科学实验室里、在各大陆之间,流传着一个神秘的故事,那是关于 Perl 与动态网站之间的不得不说的往事。
早期互联网历史中,有一些脍炙人口的开创性事件:如蒂姆·伯纳斯·李Tim Berners-Lee在邮件组上宣布[1] WWW-project 的那天,该文档随同 CERN[2] 发布的项目代码进入到了公共域,以及 1993 年 1 月的第一版 NCSA Mosaic 浏览器[3]。虽然这些独立的事件是相当重要的,但是当时的技术的开发已经更为丰富,不再是由一组的孤立事件组成,而更像是一系列有内在联系的故事。
这其中的一个故事描述的是网站是如何变成动态的,通俗说来就是我们如何使服务器除了提供静态 HTML 文档之外做更多的事。这是个流传在新闻组[4]和邮件列表间、计算机科学实验室里、各个大陆之间的故事,重点不是一个人,而是一种编程语言:Perl。
在上世纪 90 年代中后期,Perl 几乎和动态网站是同义词。Perl 是一种相对来说容易学习的解释型语言,并且有强大的文本处理特性,使得它能够很容易的编写脚本来把一个网站关联到数据库、处理由用户发送的表单数据,当然,还要创造那些上世纪 90 年代的网站的经典形象——计数器和留言簿。
类似的网站特性渐渐的变成了 CGI 脚本的形式,其全称为通用网关接口Common Gateway Interface,首个实现[5]由 Rob McCool 于 1993 年 11 月在 NCSA HTTPD 上完成。CGI 是目的是直面功能,并且在短短几年间,任何人都可以很容易的找到一些由 Perl 写的预制的脚本存档。有一个声名狼籍的案例就是 Matt's Scripts Archive[6],这是一种流行却包含各种安全缺陷的源代码库,它甚至使得 Perl 社区成员创建了一种被称为 Not Matt‘s Scripts[7] 的更为专业的替换选择。
在当时,无论是业余爱好者,还是职业程序员都采用 Perl 来制作动态网站和应用,Tim O’Reilly 创造了词汇“信息软件”infoware[8]来描述网站和 Perl 怎样成为变化中的计算机工业的一部分。考虑到 Yahoo!和 Amazon 带来的创新,O‘Reilly 写道:“传统软件在大量的软件中仅仅包含了少量的信息;而信息软件则在少量的软件中包含了大量的信息。” Perl 是一种像瑞士军刀一样的完美的小而强大的工具,它支撑了信息媒体从巨大的网站目录向早期的用户生成内容(UGC)平台的转变。
尽管使用 Perl 来制作 CGI 简直是上佳之选,但是编程语言和不断提升中的动态网站之间的关系变得更加的密切与深入。从第一个网站[9](在 1990 年的圣诞节前)出现到 1993 年 McCool 实现 CGI 的短暂时期内,Web 上的各种东西,比如表单、图片以及表格,就这么逐渐出现在上世纪 90 年代乃至后来。尽管伯纳斯·李也对这些早期的岁月产生了影响,但是不同的人看到的是 Web 不同的潜在作用,并将它推向各自不同的方向。一方面,这样的结果来自一些著名的辩论,例如 HTML 应该和 SGML 保持多近的关系[10]、是否应该实现一个图像标签[11]等等。在另一方面,在没有直接因素影响的情况下改变是极其缓慢的。后者已经很好的描述了动态网站是如何发展的。
从某种意义上说,第一个“网关”的诞生可以追溯到 1991 至 1992 年之间(LCTT 译注:此处所谓“网关”的意义请参照 CGI 的定义),当时伯纳斯·李和一些计算机科学家与超文本爱好者编写服务程序[12]使得一些特定的资源能够连接到一起,例如 CERN 的内部应用程序、通用的应用程序如 Oracle 数据库、广域信息查询系统(WAIS)[13] 等等。(WAIS 是 Web 的前身,上世纪 80 年代后期开发,其中,开发者之一 Brewster Kahle[14],是一个数字化图书管理员和 Internet Archive[15] 的创始人。)可以这样理解,“网关”就是一个被设计用来连接其它 Web、数据库或者应用程序的定制的 Web 服务器。任何的动态功能就意味着在不同的端口上运行另外一个守护进程(参考阅读,例如伯纳斯·李对于在网站上如何添加一个搜索功能[16] 的描述)。伯纳斯·李期望 Web 可以成为不同信息系统之间的通用接口,并且鼓励建立单一用途服务。他也提到 Perl 是一种强大的(甚至是不可思议)、可以将各种东西组合起来的语言。
然而,另一种对“网关”的理解指出它不一定是一个定制设备,可能只是一个脚本,一个并不需要额外服务器的低吞吐量的附加脚本。这种形式的首次出现是有争议性的 Jim Davis 的 Gateway to the U Mich Geography server[17],于 1992 年的 11 月发布在了 WWW-talk 邮件列表中。Davis 的脚本是使用 Perl 编写的,是一种 Web API 的原型,基于格式化的用户查询从另外的服务器拉取数据。我们来说明一下这两种对于网关的理解的不同之处,伯纳斯·李回复了[18] Davis 的邮件,期望他和 Michigan 服务器的作者“能够达成某种共识”,“从网络的角度来看的话”仅使用一台服务器来提供这样的信息可能会更有意义。伯纳斯·李,可能是期待着 Web 的发明者可以提出一种有秩序的信息资源访问方式。这样从不同服务器上拉取数据的网关和脚本意味着一种潜在的 Web 的质的变化,虽然不断增多,但也可能有点偏离了伯纳斯·李的原始观点。
在 Davis 的地理服务器上的网关向标准化的、低吞吐量的、通过 CGI 方式实现的脚本化网关迈进的一步中,Perl HTTPD[19] 的出现是很重要的事件,它是 1993 年初由印地安纳大学的研究生 Marc Van Heyningen 在布卢明顿Bloomington完全使用 Perl 语言实现的一个 Web 服务器程序。从 Van Heyningen 给出的设计原则[20]来看,基于使用 Perl 就不需要任何的编译过程这样一种事实,使得它能够成为一种极易扩展的服务器程序,这个服务器包含了“一个向代码中增加新特性时只要简单的重启一下就可以,而不会有任何的宕机时间的特性”,使得这个服务器程序可以频繁的加入新功能。
Perl HTTPD 代表了那种服务器程序应该是单一、特定目的的观点。相应的,这种模式似乎暗示了在 Web 开发中像这样渐进式的、持续测试的软件产品可能会最终变成一种共识。Van Heyningen 在后来提到过[21]他从头编写这样一个服务器程序的初衷是当时没有一种简便的方式使用 CERN 服务器程序来生成“虚拟文档”(例如,动态生成的页面),他打趣说使用 Perl 这样的“神之语言”来写可能是最简单的方式了。在他初期编写的众多脚本中有一个 Sun 操作系统的用户手册的 Web 界面,以及 Finger 网关[22](这是一种早期用来共享计算机系统信息或者是用户信息的协议)。
虽然 Van Heyningen 将印地安纳大学的服务器主要用来连接现存的信息资源,他和研究生们同时也看见了作为个人发布形式的潜在可能。其中一件广为人知事件是在 1993-1994 年之间围绕着一个著名的加拿大案件而公布[23]的一系列的文件、照片和新闻故事,与此形成鲜明对比的是,所有的全国性媒体都保持了沉默。
Perl HTTPD 没有坚持到现在的需要。今天,Van Heyningen 回忆起这个程序的时候认为这个程序只是当时的一个原型产品。它的原始目的只是向那些已经选择了 Gopher 作为大学的网络界面的资深教员们展示了网络的另一种利用方式。Van Heyningen 以一种基于 Web 的、可搜索的出版物索引[24]的方式,用代码回应了他的导师们的虚荣。就是说,在服务器程序技术方面关键创新是为了赢得争论的胜利而诞生的,在这个角度上来看代码做到了所有要求它所做的事。
不管该服务器程序的生命是否短暂,伴随者 Perl HTTPD 一起出现的理念已经传播到了各个角落。Van Heyningen 开始收到了获取该代码的请求,而后将它分享到了网上,并提示说,需要了解一些 Perl 就可以将它移植到其它操作系统(或者找到一个这样的人也行)。不久之后,居住在奥斯汀Austin的程序员 Tony Sanders 开发了一个被称为 Plexus[25] 的轻便版本。Sander 的服务器程序是一款全功能的产品,并且同样包含了 Perl HTTPD 所建议的易扩展性,而且添加一些新的特性如图片解码等。Plexus 直接影响了[26] Rob McCool 给 NCSA HTTPD 服务器上的脚本开发的“htbin”,并且同样影响到了不久之后诞生的通用网关接口(CGI)。
在这些历史遗产之外,感谢妙不可言的互联网时光机Internet Archive使得 Perl HTTPD 在今天依然保留在一种我们依然可以获取的形式,你可以从这里下载 tarball[27]。
对于技术世界的颠覆来说,技术的改变总是在一个相互对立的过程中。现有的技术是思考新技术的基础与起点。过时的编程形式启迪了今天人们做事的新方式。网络世界的创新可能看起来更像是对于旧技术的扩展,不仅仅是 Perl。
在萌芽事件的简单的时间轴之外,Web 历史学者也许可以从 Perl 获取更多的线索。其中一部份的挑战在于材料的获取。更多需要做的事情包括从可获取的大量杂乱的数据中梳理出它的结构,将分散在邮件列表、归档网站,书本和杂志中的信息内容组合在一起。还有一部分的挑战是需要认识到 Web 的历史不仅仅是新技术发布的日子,它同时包括了个人记忆、人类情感与社会进程等,并且这不仅仅是单一的历史线而是有许许多多条相似的历史线组合而成的。就如 Perl 的信条一样“殊途同归。There's More Than One Way To Do It.”
(题图来自:pinterest.com[28])
via: https://opensource.com/life/16/11/perl-and-birth-dynamic-web
作者:Michael Stevenson[29] 译者:wcnnbdk1 校对:wxy
本文由 LCTT[30] 原创编译,Linux中国 荣誉推出
[1]: 宣布 - https://groups.google.com/forum/#!msg/alt.hypertext/eCTkkOoWTAY/bJGhZyooXzkJ
[2]: CERN - https://tenyears-www.web.cern.ch/tenyears-www/
[3]: 第一版 NCSA Mosaic 浏览器 - http://1997.webhistory.org/www.lists/www-talk.1993q1/0099.html
[4]: 新闻组 - https://en.wikipedia.org/wiki/Usenet_newsgroup
[5]: 首个实现 - http://1997.webhistory.org/www.lists/www-talk.1993q4/0518.html
[6]: Matt's Scripts Archive - https://web.archive.org/web/19980709151514/http://scriptarchive.com/
[7]: Not Matt‘s Scripts - http://nms-cgi.sourceforge.net/
[8]: “信息软件” - https://web.archive.org/web/20000815230603/http://www.edventure.com/release1/1198.html
[9]: 第一个网站 - http://info.cern.ch/hypertext/WWW/TheProject.html
[10]: HTML 应该和 SGML 保持多近的关系 - http://1997.webhistory.org/www.lists/www-talk.1993q1/0096.html
[11]: 是否应该实现一个图像标签 - http://1997.webhistory.org/www.lists/www-talk.1993q1/0182.html
[12]: 编写服务程序 - http://info.cern.ch/hypertext/WWW/Daemon/Overview.html
[13]: 广域信息查询系统(WAIS) - https://en.wikipedia.org/wiki/Wide_area_information_server
[14]: Brewster Kahle - http://brewster.kahle.org/about/
[15]: Internet Archive - https://archive.org/index.php
[16]: 如何添加一个搜索功能 - http://1997.webhistory.org/www.lists/www-talk.1993q1/0109.html
[17]: Gateway to the U Mich Geography server - https://lists.w3.org/Archives/Public/www-talk/1992NovDec/0060.html
[18]: 回复了 - https://lists.w3.org/Archives/Public/www-talk/1992NovDec/0069.html
[19]: Perl HTTPD - https://web.archive.org/web/19970720025822/http://www.cs.indiana.edu/perl-server/code.html
[20]: 设计原则 - https://web.archive.org/web/19970720025822/http://www.cs.indiana.edu/perl-server/intro.html
[21]: 提到过 - https://web.archive.org/web/19980122184328/http://www.cs.indiana.edu/perl-server/history.html
[22]: Finger 网关 - https://web.archive.org/web/19990429014629/http://www.cs.indiana.edu:800/finger/gateway
[23]: 公布 - https://web.archive.org/web/19970720205155/http://www.cs.indiana.edu/canada/karla.html
[24]: 一种基于 Web 的、可搜索的出版物索引 - https://web.archive.org/web/19990428030253/http://www.cs.indiana.edu:800/cstr/search
[25]: Plexus - https://web.archive.org/web/19990421192342/http://www.earth.com/server/doc/plexus.html
[26]: 直接影响了 - http://1997.webhistory.org/www.lists/www-talk.1993q4/0516.html
[27]: 这里下载 tarball - https://web.archive.org/web/20011126190051/http://www.cs.indiana.edu/perl-server/httpd.pl.tar.Z
[28]: pinterest.com - https://www.pinterest.com/pin/146930006563199552/
[29]: Michael Stevenson - https://opensource.com/users/mstevenson
[30]: LCTT - https://github.com/LCTT/TranslateProject
TypeScript 的起源是由微软公司开发,其首席架构师是 Anders Hejlsberg。Anders 是 Delphi 和 C# 语言的创始人,于2012年从微软发布了 TypeScript。
TypeScript 诞生的原因是为了解决 JavaScript 的一些缺点,比如 JavaScript 缺乏强类型,没有模块化等。TypeScript 的目标是扩展 JavaScript 的能力并提高开发者的生产效率。
相较于 JavaScript,TypeScript 更接近于强类型静态编程语言。它在 JavaScript 的基础上,增加了一些静态类型检测的功能。这些功能可以帮助开发者在编写代码的时候更快速地找到潜在的错误,并且缩小了调试时的范围。
TypeScript 还提供了面向对象编程的特性,如类、泛型、接口等。这些特性可以大大提高代码的可维护性,让代码更简洁、易读、可扩展和可重构。
总而言之,TypeScript 是一个让 JavaScript 更加加强的超集语言,它提供了更多的优点和特性,使得大型项目和团队开发变得更加容易。
TypeScript 和 JavaScript 的关系是 TypeScript 扩展了 JavaScript。
即 TypeScript 是 JavaScript 的超集。
TypeScript 可以编写更高效的 JavaScript 代码,提高开发的效率和代码的可维护性。
TypeScript 提供了静态类型系统, 这使得很多编码问题在编写代码时就可以被发现并解决。而 JavaScript 是动态类型语言,因此没有这些优势,很多错误只有运行时才能被发现。
TypeScript 还提供了面向对象编程的语法。它可以使用类、接口等描述代码组织结构和功能,这些都是 JavaScript 所缺乏的。
TypeScript 的代码可以直接编译成 JavaScript,所以使用 TypeScript 编写代码时可以更加自由与灵活地选择是否使用 TypeScript 的特性。
因为 TypeScript 是 JavaScript 的超集,因此 TypeScript 的所有特性都可以在 JavaScript 中使用。可以使用类、接口等特性编写面向对象的 JavaScript 代码,同时使用 JavaScript 特有的语法和特性。
总而言之,TypeScript 和 JavaScript 是强关联、兼容与相互促进的。它们的关系如同 XML 与 HTML 之于 SGML(标准通用标记语言)那样,TypeScript 是 JavaScript 的更高级的扩展,JavaScript 是通用编程语言,而 TypeScript 扩展了它。
TypeScript 的主要特点有:
总而言之,TypeScript 主要特点包括静态类型、支持 ES6+ 新特性、支持面向对象编程、可扩展、跨平台兼容性、规范化、类型注解等。这些优点使得 TypeScript 得到了广泛的应用和支持,并成为了一个备受关注的编程语言。
安装 TypeScript,步骤如下:
npm install -g typescript
这个命令将会全局安装最新版本的 TypeScript。
tsc -v
如果命令行返回了 TypeScript 的版本号,则表示 TypeScript 安装成功。
现在你已经成功安装了 TypeScript!
TypeScript 是一种开放源代码编程语言,它可以与多个流行的集成开发环境 (IDE) 配合使用,以提高开发效率。
以下是几种常用的 IDE 的 TypeScript 集成方法:
总的来说,使用 TypeScript 的好处是它可以提供更好的代码可读性和可维护性。无论你使用哪种 IDE,TypeScript 的集成只需要简单的步骤,以便更高效的创建高质量的 TypeScript 应用程序。
TypeScript 代码需要被编译成可运行的 JavaScript 代码,因为浏览器和 Node.js 无法直接运行 TypeScript。
以下是一些编译 TypeScript 的方法:
tsc filename.ts
tsc
这将编译 tsconfig.json 中指定的所有 TypeScript 文件。
以上是几种编译 TypeScript 的方法。为了更高效地编写 TypeScript 代码,推荐使用 tsconfig.json 文件来编译整个 TypeScript 项目。
在 TypeScript 中,数据类型依据值的类型进行分类,主要包括以下类型:
以上是 TypeScript 中常用的数据类型。使用正确的数据类型可以提高代码的可读性和性能,并且避免在代码运行时出现错误。
在 TypeScript 中,有两种声明变量的方式:使用 var 和使用 let 关键字。在 ES6 中,let 关键字是引入的,它是块级作用域。除了使用 var 和 let 之外,还可以使用 const 关键字来声明常量,一旦赋值之后值不会改变。以下是这三种声明方式的例子:
var x=10;
function example() {
var y=2;
}
console.log(x); // 10
console.log(y); // 报错,y 在函数作用域之外不可用
let x=10;
function example() {
let y=2;
if (true) {
let z=3;
}
}
console.log(x); // 10
console.log(y); // 报错,y 在函数作用域之外不可用
console.log(z); // 报错,z 在块级作用域之外不可用
const x=10;
// x=5; 报错,常量的值一旦被赋值后不能改变
总的来说,使用 let 和 const 关键字声明变量和常量可以避免作用域和重新赋值的问题。在 TypeScript 中,推荐使用 let 和 const 关键字来声明变量和常量,以提高代码的可读性和可维护性。
在 TypeScript 中,函数是一种非常重要的语言特性。函数是一段可重用的代码块,用于执行某个特定的任务。
以下是 TypeScript 中常用的函数相关的语法:
function add(x: number, y: number): number {
return x + y;
}
function drawImage(url: string, width?: number, height?: number): void {
// 使用默认的高度和宽度
if (!width) {
width=100;
}
if (!height) {
height=100;
}
// 加载图像并绘制图像
}
function multiply(multiplier: number, ...theNumbers: number[]): number {
return theNumbers.reduce((prev, curr)=> {
return prev * curr;
}, multiplier);
}
let square=function(x: number): number {
return x * x;
};
let add=(x: number, y: number): number=> {
return x + y;
};
总的来说,函数是 TypeScript 中的重要组成部分,提供了一种强大、可重用的代码块来执行特定的任务。在声明函数时,可以为函数指定参数和返回值类型,并且可以使用可选参数、默认值、剩余参数、匿名函数和箭头函数等语法。
TypeScript 是一种静态类型的开发语言,它是 JavaScript 的超集,可以编写面向对象(OOP)的代码。TypeScript 支持类、继承、抽象类、接口等 OOP 概念,让开发者编写更加结构化和可维护的代码。
下面是 TypeScript 中声明类的基本语法:
class Person {
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName=firstName;
this.lastName=lastName;
}
getFullName(): string {
return `${this.firstName} ${this.lastName}`;
}
}
上面的代码定义了一个名为 Person 的类,它拥有两个公共的属性 firstName 和 lastName,还有一个构造函数用来初始化这两个属性。getFullName() 是一个公共方法,用来返回 Person 实例的全名。
接下来是如何创建 Person 类的实例:
const person=new Person('John', 'Doe');
console.log(person.getFullName());
上面的代码会输出 John Doe。
继承是面向对象编程的一个重要概念, TypeScript 也支持类继承。下面是一个继承案例:
class Employee extends Person {
companyName: string;
constructor(firstName: string, lastName: string, companyName: string) {
super(firstName, lastName);
this.companyName=companyName;
}
getFullName(): string {
return `${super.getFullName()} - ${this.companyName}`;
}
}
上面的代码定义了一个名为 Employee 的类,继承自 Person 类。Employee 类有一个新的属性 companyName,还有一个构造函数和一个重写的 getFullName() 方法。
现在我们可以创建 Employee 类的实例:
const employee=new Employee('John', 'Doe', 'ABC Corp');
console.log(employee.getFullName());
上面的代码会输出 John Doe - ABC Corp。
TypeScript 的面向对象编程概念还包括抽象类、接口、访问修饰符等,这些概念能够协助开发者管理类的状态和行为,让代码更加清晰易懂。
TypeScript 具有静态类型检查的特性,它可以使用类型注解来明确变量、参数、函数等的类型。此外,类型注解还可以提高代码可读性和可维护性,减少类型相关的错误。
下面是一些基本的类型注解例子:
// 声明变量 age 为 number 类型
let age: number=30;
// 声明数组 numbers 中每个元素都为 number 类型
let numbers: number[]=[1, 2, 3, 4];
// 声明对象 person 中的属性 firstName 和 lastName 分别为 string 类型
let person: { firstName: string, lastName: string }={ firstName: 'John', lastName: 'Doe' };
// 声明函数 getFullName 参数 firstName 和 lastName 都为 string 类型,返回 string 类型
function getFullName(firstName: string, lastName: string): string {
return `${firstName} ${lastName}`;
}
当类型注解不匹配时,TypeScript 会给出类型错误提示。例如,下面的代码会在编译时报错:
let name: string='John';
// 下面这行代码会编译时错误,因为 'number' 类型不能赋值给 'string' 类型
name=30;
除了上述的基本类型,TypeScript 还提供了很多内置类型和高级类型,例如元组、枚举、联合类型、交叉类型等。使用这些类型注解,可以让开发者更好地管理和维护代码。
TypeScript 中的泛型(Generics)是实现可重用性的一种强大工具,它可以用来创建具有灵活参数类型的函数、类和接口。泛型可以让代码变得更加可读、可维护和可扩展。
下面是一个简单的泛型函数示例:
function getArray<T>(items: T[]): T[] {
return new Array().concat(items);
}
let numArray: number[]=[1, 2, 3, 4];
let strArray: string[]=['one', 'two', 'three'];
let concatNumArray: number[]=getArray<number>(numArray);
let concatStrArray: string[]=getArray<string>(strArray);
上面的代码使用了一个泛型函数 getArray,它接受一个类型为 T 的数组 items 作为参数,然后返回一个类型为 T 的新数组。在上面的调用中,我们分别使用了 number 和 string 作为类型参数调用了 getArray 函数,返回了新的数组类型。
除了泛型函数,TypeScript 中还有泛型类和泛型接口。下面是一个泛型类示例:
class Queue<T> {
private data: T[]=[];
push(item: T) {
this.data.push(item);
}
pop(): T | undefined {
return this.data.shift();
}
}
let q=new Queue<number>();
q.push(1);
q.push(2);
console.log(q.pop()); // output: 1
console.log(q.pop()); // output: 2
上面的代码展示了一个名为 Queue 的泛型类,它包含一个私有数据成员 data 和两个方法 push 和 pop。可以看到,在实例化 Queue 类时,我们可以指定泛型类型为 number,然后向队列中加入了两个 number 类型的元素。最后通过 pop 方法分别弹出两个元素并打印结果。
通过泛型,TypeScript 可以实现更加灵活的代码类型,便于复用和维护,适用于多种场景。
TypeScript 中的接口是一种定义代码契约、规范行为的方式,它主要用于描述对象的形状和行为。接口可以让开发者明确代码的输入和输出,提高代码的健壮性和可读性。
下面是一个基本的接口示例:
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
function greet(person: IPerson) {
console.log(`Hello, ${person.firstName} ${person.lastName}!`);
}
let user={ firstName: 'John', lastName: 'Doe', age: 30 };
greet(user);
上面的代码中,我们定义了一个名为 IPerson 的接口,它包含三个属性:firstName、lastName 和 age。然后我们定义了一个名为 greet 的函数,它接受一个类型为 IPerson 的参数,函数内部根据传入参数输出字符串。最后我们定义了一个变量 user,它包含了 firstName、lastName 和 age 三个属性,并把它传入 greet 函数中。
在 TypeScript 中,接口可以表示更加复杂的对象形状,包括可选属性、只读属性、函数类型和继承等。例如,下面是一个包含可选属性和函数类型的接口示例:
interface IEmployee {
firstName: string;
lastName: string;
age?: number;
getFullName: ()=> string;
}
let employee: IEmployee={
firstName: 'John',
lastName: 'Doe',
getFullName: function() {
return `${this.firstName} ${this.lastName}`;
}
};
console.log(employee.getFullName()); // output: John Doe
上面的代码中,我们定义了一个名为 IEmployee 的接口,其中 age 属性是可选的,getFullName 属性是函数类型。然后我们创建了一个名为 employee 的对象,它包括 firstName、lastName 和 getFullName 三个属性,并通过 getFullName 属性返回了全名字符串。
总之,接口是一种强大的代码规范和约束方式,能够提高代码的可读性、可维护性和可扩展性,适用于多种场景。
TypeScript 可以与各种框架集成,使开发者能够使用 TypeScript 强大的类型检查和自动补全功能,提高代码可靠性和开发效率。
下面是一些 TypeScript 与常见框架集成的简单示例:
在 Vue.js 中使用 TypeScript 可以提供更加明确的代码类型和语法检查,通过安装 Vue.js 的官方插件 vue-cli-plugin-typescript 可以轻松的将 Vue.js 与 TypeScript 集成。同时,Vue.js 的文档中也提供了 TypeScript 的使用指南。
使用 TypeScript 和 Vue.js 来编写一个简单的组件:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class MyComponent extends Vue {
private message='Hello, World!';
}
</script>
上面的代码采用了 TypeScript 语法,使用了 Vue.js 的装饰器 @Component,声明了一个名为 MyComponent 的组件,并给出了一个私有的属性 message 并赋值为字符串。
在 React 中可以通过多种方式使用 TypeScript,例如使用 create-react-app 来创建一个基于 TypeScript 的项目框架,或者手动配置 TypeScript 和 React 的集成环境。React 提供了完整的官方文档来说明如何使用 TypeScript 构建 React 应用。
以 create-react-app 为例,创建基于 TypeScript 的 React 应用框架示例:
npx create-react-app my-app --typescript
然后创建一个名为 MyComponent 的 React 组件:
import React from 'react';
interface IProps {
message: string;
}
const MyComponent: React.FC<IProps>=({ message })=> {
return (
<div>
<p>{message}</p>
</div>
);
};
上面的代码采用了 TypeScript 语法,定义了一个名为 IProps 的接口,表示 MyComponent 组件的属性类型。通过使用 React.FC 泛型来使用这个接口,使得 MyComponent 组件接收一个名为 message 的字符串类型的属性,返回一个包含一个 p 标签的 div 元素并输出 message 属性的内容。
结论:
TypeScript 可以与各种框架集成,例如 Vue.js、React、Angular 等,使开发者能够使用 TypeScript 强大的类型检查和自动补全功能来提高代码可靠性和开发效率,适合于大型和复杂的应用程序开发。
TypeScript 在以下场景中拥有较为广泛的应用:
总之,TypeScript 可以被广泛应用于各种类型的项目开发中,提高代码的可靠性、可读性和可维护性,适用于大多数的 Web 开发项目。
下面是两个 TypeScript 应用案例的简介:
Angular 是 Google 推出的一款前端 MVC 框架,它完全采用 TypeScript 编写。Angular 提供了非常完整的组件化开发框架,拥有很高的可复用性和可维护性。Angular 的 TypeScript 特性,如静态类型检查、类型推导等等,能够大大提高代码的可读性和可维护性。
NestJS 是一个用于构建可扩展和高效的 Web 应用程序的 Node.js Web 框架,它使用 TypeScript 编写。NestJS 借鉴了 Angular 中的设计思路和模式,提供了类似 Angular 的装饰器、依赖注入和模块化编程的方案,使得开发者能够更快速、高效地构建 Node.js 应用程序。
总体来说,TypeScript 能够在多个领域发挥作用,提高代码的可扩展性和可维护性,同时也能增强开发者对代码的把控和安全性。无论是大型前端框架还是后端 Node.js 应用程序,都可以通过 TypeScript 发挥技术和业务价值。
下面是一些编写 TypeScript 代码的建议:
总之,编写 TypeScript 代码需要一定的 JavaScript 基础和 TypeScript 特性的掌握,同时需要写出详细的类型声明,合理利用 TypeScript 的工具和插件,并熟悉 TypeScript 的编译过程。
以下是一些遵循良好的 TypeScript 代码风格的指南:
总之,遵循良好的 TypeScript 代码风格可以提高代码的可读性、可维护性和可扩展性,同时也能够更好地协作和构建具有高质量的代码库。
TypeScript 与 JavaScript 的兼容性问题主要体现在两个方面:
1. TypeScript 编译后的 JavaScript 代码是否能够运行在原生的 JavaScript 环境中。
解决方案:TypeScript 支持通过编译选项配置目标 JavaScript 版本。通过指定目标 JavaScript 版本,可以确保生成的 JavaScript 代码能够在目标环境中运行。同时,TypeScript 还提供了对 ES5、ES6、ES7 的语言特性支持,可以根据实际项目需求选择相应的编译选项。
2. JavaScript 库或框架中的声明文件与 TypeScript 声明文件不一致,导致类型错误和运行时错误。
解决方案:一种方法是使用第三方库的 TypeScript 版本,如果不存在,则自己创建类型声明文件,或者使用第三方提供的类型声明文件。
另外,建议在使用 JavaScript 库或框架时,尽量避免使用 any 类型,以避免类型错误和难以维护的代码。可以通过为第三方库编写类型声明文件的方式来避免 any 类型的使用。
总之,TypeScript 和 JavaScript 之间的兼容性问题可以通过相应的编译选项和类型声明文件来解决。同时,尽可能减少对 any
类型的使用也可以提高代码质量和可读性。
以下是几个 TypeScript 中常用的异步控制工具:
1. Promise
Promise 是 ES6 中引入的一种异步编程解决方案。在 TypeScript 中,可以借助 Promise 来处理异步任务的完成和失败,使得代码更加易读和易维护。
2. Async/Await
Async/Await 是 ES2017 中引入的一种异步编程解决方案,可以直接处理基于 Promise 的异步操作。在 TypeScript 中,可以使用 Async/Await 语法来进行同步式的异步编程,简化代码结构,提高代码质量。
3. RxJS
RxJS 是一个使用 Observables 来处理异步和事件的库。Observables 是表示异步数据流的对象,具有强大的操作符和方法来处理数据的变换和流控制。因此,在 TypeScript 中使用 RxJS 可以极大地简化异步操作的代码,同时也提供了更多的数据流处理的能力。
4. Bluebird
Bluebird 是一个 Promise 库,支持 Promise 的链式调用、多个 Promise 的并行和序列等操作。在 TypeScript 中使用 Bluebird 可以让我们更好地控制 Promise 的流程,从而简化异步异步程序的编写。
综上所述,以上这些工具都是 TypeScript 中常用的异步控制工具,可以让我们更好地处理异步任务。在选择工具时,可以根据实际需求选择合适的工具,以便提高代码质量、可读性和可维护性。
以下是常用的 TypeScript 单元测试工具:
1. Jest
Jest 是一个流行的 JavaScript 单元测试框架,可以用于测试 JavaScript 和 TypeScript 代码。它具有简单易用、快乐生产、提供了覆盖率报告、支持并发测试等特点。Jest 可以很容易地集成 CI/CD 工具,并在开发过程中持续运行测试,并报告任何可能的错误。
2. Mocha
Mocha 是另一个流行的 JavaScript 单元测试框架,它可以用于测试 JavaScript 和 TypeScript 代码。它具有支持任何断言库、支持异步和同步代码测试、易于扩展等特点。Mocha 还支持在浏览器和 Node.js 环境中运行测试。
3. Chai
Chai 是一个可扩展的 BDD/TDD 断言库,可以与 Mocha 和其他 JavaScript 测试框架一起使用。Chai 具有灵活的语法和支持链式表达式等优点,可以帮助我们更好的编写测试代码,以确保代码质量和可读性。
4. Sinon
Sinon 是一个 JavaScript 测试工具库,可以帮助我们模拟对象、函数和 API 调用。在 TypeScript 中,我们可以使用 Sinon 来测试异步代码、模拟函数的返回值和异常等。
5. Testcafe
Testcafe 是一个跨平台自动化浏览器测试工具。它可以在真实的浏览器中运行测试,以提供最真实的测试结果。Testcafe 也支持 TypeScript,在测试代码中具有类型检查的能力。
总之,以上这些工具都可以用于 TypeScript 单元测试,我们可以根据实际需求选择适合的工具。无论是 Jest、Mocha 还是 Chai、Sinon,甚至是 Testcafe,它们都有着强大的测试和断言能力,帮助我们更好地测试我们的 TypeScript 代码。
以下是常用的 TypeScript 依赖注入工具:
1. InversifyJS
InversifyJS 是一个轻量级的 TypeScript 依赖注入库,它可以帮助我们轻松地进行依赖注入和控制反转,以便更好地组织我们的应用程序。其特点包括基于装饰器注入、支持异步加载、可扩展和易于调试等。
2. tsyringe
tsyringe 是另一个轻量级的 TypeScript 依赖注入工具,它提供了基于装饰器和类型元数据的依赖注入机制,以及类型安全、可配置和可扩展的特性。tsyringe 还支持实例范围、生命周期、条件注入和延迟加载等高级特性。
3. Awilix
Awilix 是一个功能齐全的 JavaScript 依赖注入库,可以完美地支持 TypeScript。它提供了类似 InversifyJS 和 tsyringe 的基于装饰器的注入机制,以及可扩展、可测试和可配置的特性。Awilix 还可以与其他 JS 技术,如 Express、Passport 和 Socket.IO,无缝集成。
4. Nest
Nest 是一个基于 Node.js 和 TypeScript 的应用程序框架,致力于提供高层次的抽象和易于开发的解决方案。Nest 内置了一个依赖注入容器,可以直接支持控制反转和依赖注入,而不需要使用第三方库。
总之,以上这些工具都是常用的 TypeScript 依赖注入工具,我们可以根据实际需求选择适合我们的工具。无论是 InversifyJS、tsyringe,还是 Awilix 和 Nest,它们都有着不同的优点和特点,可以帮助我们更好地组织和管理我们的应用程序代码。
以下是 TypeScript 的发展趋势:
1. 与 React、Angular、Vue 等前端框架一起使用
由于 TypeScript 具有类型安全、可读性和可维护性等特点,与 React、Angular、Vue 等前端框架一起使用的趋势将会继续发展。React、Angular、Vue 三大框架都对 TypeScript 的支持不断增强,许多流行的 UI 库和组件库已经开始采用 TypeScript 进行开发和维护。
2. 实现更好的类型系统和编译器特性
TypeScript 已经拥有了强大的类型系统和编译器特性,而未来的发展趋势将集中在使它们更好,并进一步提高代码质量和开发效率。例如,TypeScript 的类型系统可以进一步支持对连锁方法、装饰器、解构等高级语言特性的类型推导和检查。
3. 集成更多的编辑器和 IDE
TypeScript 已经得到了许多流行的编辑器和 IDE 的支持,例如 VS Code、WebStorm、Atom 等等。未来,TypeScript 可能会更多地与其他工具和平台进行集成,以进一步提高开发效率、便捷性和可读性。
4. 支持 WebAssembly
WebAssembly 是一种低级别的字节代码格式,目前已经得到了越来越广泛的支持。TypeScript 可能会在未来支持 WebAssembly,从而让开发者能够更加轻松地编写和调试 WebAssembly 应用程序。
综上所述,TypeScript 的发展趋势是与前端框架一起使用、实现更好的类型系统和编译器特性、集成更多的编辑器和 IDE,以及支持 WebAssembly。这些趋势将进一步提高 TypeScript 的普及率和应用场景,帮助开发者更高效地编写高质量的应用程序。
TypeScript 对企业级应用的贡献主要体现在以下几个方面:
1. 可维护性和代码质量
TypeScript 的类型系统可以帮助开发者更好地描述和控制代码行为,减少代码中的潜在错误和漏洞。TypeScript 还提供了一系列的开发工具和功能,如类型推导、高级语法和编辑器工具支持,这些都可以帮助开发者更好地管理和维护企业级应用,提高代码质量和可维护性。
2. 可读性和可扩展性
TypeScript 的类型注解和代码结构可以帮助人类开发者更好地理解和阅读代码,使得代码更加易于理解和扩展。TypeScript 还提供了与现代前端框架(如 React、Vue、Angular)和后端系统(如 Node.js)进行深度集成的能力,使得开发者可以更好地利用现有的工具和技术来开发企业级应用。
3. 生态和社区
TypeScript 的持续发展和社区推动也为企业级应用的发展做出了贡献。TypeScript 有一个庞大的社区和生态系统,开发者可以在这个社区中找到大量的支持、文档、教程、工具和解决方案,以满足日益增长的企业需求。
4. 敏捷开发和自动化测试
TypeScript 的静态类型系统可以帮助开发者更好地理解软件代码和架构,同时也可以快速识别代码中的错误和故障。这些特性还可以帮助企业在软件开发和自动化测试方面更加运用敏捷开发和DevOps实践,以加快软件应用的交付和上线速度。
综上所述,TypeScript 对企业级应用的贡献主要包括提高可维护性和代码质量、提高可读性和可扩展性、为企业级应用提供具有价值的生态和社区,以及支持敏捷开发和自动化测试。这些贡献使得企业级应用可以更加高效、可靠和安全地运转,满足企业级应用的需求。
TypeScript 和 JavaScript 均为主流的编程语言,各自有着不同的应用场景和发展趋势。
以下是 TypeScript 与 JavaScript 的趋势比较:
1. 类型系统
TypeScript 与 JavaScript 最大的差异在于类型系统,TypeScript 进一步强化了 JavaScript 的类型系统,使得开发者能够更加准确和安全地编写代码。随着 TypeScript 的不断发展,类型系统将成为 TypeScript 与 JavaScript 的又一重要区别。
2. 支持 frameworks
TypeScript 目前得到了 React、Vue 和 Angular 等流行的前端框架的广泛支持,这些框架提供了更多的Typing和其他TypeScript功能。与此相比,JavaScript 的支持范围更广,无论前后端开发和框架都可以使用。
3. 社区生态
JavaScript 已经拥有了一个经过多年发展的社区和生态系统,在许多项目中都得到了广泛的应用和支持。然而,TypeScript 在近年来也逐渐发展壮大,拥有庞大的社区和生态系统,并且正在获得更多的关注和应用。
4. 学习成本
由于 TypeScript 是建立在 JavaScript 基础之上进行扩展的,因此学习 TypeScript 的过程会比学习 JavaScript 的过程更具挑战性。需要掌握更多的 TypeScript 语言特性和类型系统,此外还需要大量的实践和训练来应对类型推导和类型判断等问题。
综上所述,TypeScript 和 JavaScript 都有着各自的优点和特点。TypeScript 发展的趋势是越来越好的类型系统、更广泛的框架和生态支持,而 JavaScript 发展的趋势则主要体现在更普及和更广泛的应用场景。在实际应用中,我们可以根据项目的具体需求选择 TypeScript 或 JavaScript,或者两者结合使用,以便更好地满足应用程序的需求。
以下是 TypeScript 的优点:
1. 更好的可读性和可维护性
TypeScript 引入了类型注解和类的概念,可以显著提高代码的可读性和可维护性。这些特性可以让开发者更好地了解代码的行为,同时也可以排除一些常见的编程错误。
2. 更安全的编程环境
TypeScript 可以通过类型检查,避免在代码中出现类型错误,在编码阶段就暴露一些潜在的问题,可以避免一些错误在运行时才出现,提高了代码的稳定性和可靠性。同时,TypeScript 还可以减少由于类型转换错误导致的运行时错误,提高代码的安全性。
3. 更好的 IDE 支持
TypeScript 可以提供比 JavaScript 更好的类型验证,所以绝大部分 IDE 可以对 TypeScript 进行语法和类型补全。这样可以在编码过程中减少手动输入和抵御语法错误,从而提高开发效率。
4. 更好的与第三方库的集成
现在大量的 JavaScript 库已经使用 TypeScript 进行开发,很多流行的前端框架和库,包括 React、Angular 和 Vue,都对 TypeScript 的支持非常友好。使用 TypeScript 可以更好地集成这些第三方库和框架,同时保持类型安全和可维护性。
5. 更快的开发速度和更少的错误
TypeScript 可以提高开发团队的效率,同时也能够减少代码中的错误,降低修复错误的成本和时间。与传统的 JavaScript 相比,TypeScript 精准的类型检查和更好的可组合性可以在项目开发中更自信地进行迭代和协作。
综上所述,TypeScript 具有更好的可读性和可维护性、更安全的编程环境、更好的 IDE 支持、更好的第三方库的集成以及更快的开发速度和更少的错误等优点。这些优点使得 TypeScript 在日益增长的应用场景中被广泛应用,可为企业级应用和后端项目节省大量时间和资源。
TypeScript 作为一门面向对象和静态类型的编程语言,与其他编程语言有着一些共性和差异。
TypeScript 是基于 JavaScript 的一种超集,它扩展了 JavaScript 的基础类型系统和语法,提高了代码的可读性和可维护性。TypeScript 支持与 JavaScript 代码无缝协作,并且可以直接编译成 JavaScript 代码运行在浏览器或者 Node.js 环境中。
与 Java 不同的是,TypeScript 是一种面向对象语言,但是它不像 Java 那样强制使用类和接口来构造对象,而是允许使用更加灵活的类型和架构。此外,TypeScript 拥有更短的开发环节、更容易学习、更少的等待时间、更强大的 IDE 支持以及更丰富的社区支持等优点。
与 Python 相比,TypeScript 拥有更加强大的类型系统和静态类型检查,可以帮助开发者避免在使用时出现一些类型和语法错误,并且可以提供更好的 IDE 支持。Python 拥有更好的科学计算、人工智能等方面的扩展库和生态支持。
TypeScript 和 C# 都是由 Microsoft 开发和维护的编程语言,它们有许多共性,例如静态类型检查、强类型和面向对象等特点。相比于 C#,TypeScript 更加轻量、便捷、灵活,开发团队需要考虑更多的开发效率和代码的可读性。
综上所述,TypeScript 与 JavaScript、Java、Python 和 C# 等语言有许多相似性和差异性。相互比较时需要考虑每种语言的特点和使用环境,选择最适合当前项目的语言。
以下是使用 TypeScript 时的一些建议:
1. 评估项目框架和技术栈
在使用 TypeScript 之前,需要考虑项目的框架和技术栈是否支持 TypeScript。通常,大多数流行的前端框架和库,包括 React、Vue 和 Angular 都对 TypeScript 的支持非常友好。同时也需要考虑是否使用 TypeScript 对于团队或项目具有助益。
2. 开启严格模式
TypeScript 严格模式(strict mode)可以让 TypeScript 提供更强的类型推断和类型检查,从而减少代码中的错误和漏洞。建议项目初期就开启严格模式,确保代码的质量和稳定性。
3. 确定合适的类型
TypeScript 可以为变量、函数、对象和属性定义类型,建议在编写代码时使用合适的类型。这样可以提高代码的清晰度和可读性,并且可减少一些开发中的错误。
4. 学习 TS 的特性
学习 TypeScript 的特性和语法是使用 TypeScript 的关键,建议利用在线资源或书籍系统地学习 TypeScript。掌握更多的 TypeScript 特性,使其成为企业级应用的基础。
5. 利用 TypeScript 工具和插件
TypeScript 支持许多优秀的工具和插件,包括编译器、代码检查器、自动补全等。合理的使用这些工具和插件可以大大提高开发者的开发效率和代码质量。
综上所述,使用 TypeScript 需要考虑项目框架和技术栈的适配性,建议开启严格模式、确定合适的类型、充分了解 TypeScript 的特性,以及利用 TypeScript 工具和插件来协助开发。这些建议可以使开发者更好地利用 TypeScript 来提高项目质量,并帮助团队更好地管理和维护代码库。
页开发者今天谈论的是框架、核心、网络应用程序和集成, 但是他们几乎没有为所有这些都是基于 HTML 的语言留下一个词语。 自从万维网诞生以来, 超文本标记语言就一直和我们在一起, 并且与互联网一起进化, 提供了一种简单易用的网页创建方式。 没有他们, 就没有网站可以存在——即使是那些完全用 Flash 构建的网站(当时有相当多的网站)需要它来嵌入他们的互动动画。 无处不在, 从谷歌搜索结果到移动网络应用。 现在, 在第一次实施25年之后, 让我们简单地回顾一下它的历史。
超文本标记语言最早是由著名的万维网发明家蒂莫西 · 约翰 ·"蒂姆"· 伯纳斯-李爵士首次提出。 他基于 SGMLguid 构建了这个简单的标记语言, 这是欧洲核子研究委员会内部使用的标准文档格式。 第一个公开的语言描述只包含了18个元素, 除了超链接标签, 所有这些元素都受到 SGMLguid 的启发。
今天可用的最早的 HTML 文档有以下代码:
第一个关于 HTML 规范的提案是1993年中期由 Berners-Lee 和 Dan Connolly 提出的一个名为"超文本标记语言"的网页草案, 于1993年中期出版, 因此这是正式生成这种语言的时候。 这个草案连同1994年到期的 HTML + 草案, 直到1995年因特网工程工作队(IETF)完成了"HTML 2.0"规范。 从那时起, 事情发生了很快的一段时间-HTML 3.2于1997年1月发布, 接着是同年12月的 HTML 4.0。 一年之后, W3C 发布了 HTML 4.01规范, 这些仍然是这种语言十多年来唯一的版本。
Html5是自1999年 HTML 4.01版本发布以来对 HTML 规范的第一次重大改革——正如许多人所说的那样, 终于在1999年发布了 HTML 4.01。 这也给浏览器的标记提供方式带来了严重的变化, 这些改变早就应该发生了。 除其他外, 它还增加了一种本地处理多媒体和图形内容的方法, 并且增加了新的页面结构元素, 以增强文档的语义内容。
5.0成为2014年的一个推荐, HTML 5.1在2016年遭遇了同样的命运, HTML 5.2在2017年12月14日作为 W3C推荐标准发布。 这就是我们今天的立场。
*请认真填写需求信息,我们会在24小时内与您取得联系。