TypeScript与JavaScript的区别和基础语法对比

做前端挺久了,之前是一直使用JavaScript进行开发,时间长了发现现在的主流框架都已经开始向TypeScript方向靠拢了,正好公司也给了学习的机会,就把这几天的学习成果分享一下。

TypeScript与JavaScript是目前项目开发中较为流行的两种脚本语言,我们已经知道TypeScript是JavaScript的一个超集,就是覆盖了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法。但是他们之间又有什么样的区别呢?我带你们了解一下。

简要介绍一下TypeScript

TypeScript 是 Microsoft 开发和维护的一种面向对象的编程语言。它是 JavaScript 的超集,包含了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法。

TypeScript具有以下特点:

  • TypeScript 是 Microsoft 推出的开源语言,使用 Apache 授权协议
  • TypeScript 增加了静态类型、类、模块、接口和类型注解
  • TypeScript 可用于开发大型的应用
  • TypeScript 易学易于理解

JavaScript的特点就不介绍了,大家都已经非常熟悉了。

TypeScript的优势

下面列举 TypeScript 相比于 JavaScript 的显著优势:

1. 静态输入

静态类型化是一种功能,可以在开发人员编写脚本时检验错误,查找并修复错误是当今开发团队的迫切需求。有了这项功能,就会允许开发人员编写更健壮的代码并对其进行维护,以便使得代码的质量更好、更清晰,后期维护更方便。

2. 大型项目的开发

有时为了改进开发项目,需要对代码库进行小的增量更改,这些小小的变化可能会产生严重的、意想不到的结果,因此有必要撤销这些变化。使TypeScript工具来进行重构,变得更容易更快捷。

3. 更好的协作

当开发大型项目时,会有许多的开发人员,此时乱码和错误的机会也会增加。类型安全是一种在编码期间检测错误的功能,而不是在编译项目时检测错误,这位开发团队创建了一个更高效的编码和调试过程。

4. 更强的生产力

干净的ECMAScript 6 代码,自动完成和动态输入等因素有助于提高开发人员的工作效率。这些功能也 有助于编译器创建优化的代码。

JavaScript的优势

相比较TypeScript,JavaScript也有一些非常明显的优势:

1. 人气

JavaScript的开发者社区仍然是巨大而活跃的,在社区中可以很方便的找到大量成熟的开发项目和可用资源。

2. 学习成本

由于JavaScript 语言发展的比较早,也比较成熟,所以仍有一大批开发人员坚持使用后他们熟悉的脚本语言JavaScript,而不是学习TypeScript。更多小白先接触 JavaScript 的原因也是他的人气更足,资源更多,可以在学习的道路上少走很多弯路少踩很多坑。

3. 本地浏览器支持

TypeScript 代码需要被编译,编译后输出 JavaScript 代码,这是 TypeScript 代码执行时的一个额外的步骤。

4. 不需要注释

为了充分利用 TypeScript 特性,开发人员需要不断注释他们的代码,这可能会使项目效率降低。

5. 灵活性

JavaScript 的灵活性更足一些,一些开发人员更喜欢灵活脚本语言。

JavaScript 和 TypeScript 的主要差异

TypeScript 可以使用JavaScript 中的所有代码和编码概念,TypeScript 是为了使JavaScript 的开发变得更加容易而创建的。例如:TypeScript 使用类型和接口等概念来描述正在使用的数据,这使开发人员能够快速检测错误并调试应用程序。

  • TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。
  • JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。
  • TypeScript 通过类型注解提供编译时的静态类型检查。
  • TypeScript 中的数据要求带有明确的类型,JavaScript不要求。
  • TypeScript 为函数提供了缺省参数值。
  • TypeScript 引入了 JavaScript 中没有的“类”概念。
  • TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。

开发中如何选择

TypeScript 正在成为开发大型编码项目的有力工具。因为其面向对象编程语言的结构保持了代码的清洁、一致和简单的调试。因此在应对大型开发项目时,使用 TypeScript 更加合适。如果有一个相对较小的编码项目,似乎没有必要使用 TypeScript,只需使用灵活的 JavaScript 即可。

TypeScript和JavaScript的基础语法对

JavaScript

数据类型

JavaScript的数据类型分为2大类:原始数据类型和引用数据类型
原始数据类型:object(对象)、number(数值)、string(字符串)、boolean(布尔值)、null、undefined。
引用数据类型:object类型的Array(数组)、Data、function。

JavaScript中的变量

js 中变量的声明: var 变量名 = 值
js 中变量的使用注意事项:

  • js 中的变量的名称和Java中标识符的命名保持一致就可以了。
  • js 中变量名称是可以重复的,但是后者的名称值会把前者的名称值覆盖掉。
  • js 中末尾即使没有分号结束也是可以的,但是不推荐大家这样书写。

JavaScript中的函数

在ES3 里面定义函数的关键字是 function,而在ES6 里面定义函数是可以不需要function关键字的。
在ES3 到 ES6 之间定义函数的使用function关键字。

var num = 1;
//无参数
var fn = function(){}
//无参有反
function fn(){return num;}
//有参有反
function fn(num){return num;}
//用ES6实现的
var fn = num=>num;
var fn = (num)=>num;

TypeScript

TypeScript支持与JavaScript几乎相同的数据类型,在JavaScript的基础上增加了枚举类型方便我们使用。

数据类型

布尔值

最基础的数据类型就是简单true和false值,在TypeScript和JavaScript里面叫做Boolean值。
定义变量的语法:

let bol:boolean=true;

number(数字类型)

这个和JavaScript里面的是一样的,TypeScript里面的所有数字都是浮点数,这些浮点数的类型都是number,吃了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制的字面量。

例如:

//十进制或者整数
let num:number = 3;
//十六机制
let num0X:number = 0xf00d;
//二级制
let num0b:number = 0b1010;
//八进制
let num0o:number = 0o7114;

string(字符串)

在这里和JavaScript里面定义字符串的数据可以用单引号引起来也可以用双引号引起来。

语法:

let name:string ='bob';
name = "smith";

你还可以使用模板字符串,它可以定义多行文本和内嵌表达式。这种字符串是被反引号包围,并且以${}
这种形式嵌入表达式。

举例:

let name: string = `Gene`;
let age: number = 37;
//调用姓名变量 年龄变量
let sentence: string = `Hello, my name is ${ name }.I'll be ${ age + 1 } years old next month.`;

这个与下面定义sentence的效果相同:

let sentence: string = "Hello, my name is " + name + ".\n\n" +"I'll be " + (age + 1) + " years old next month.";

数组

在Typescript中定义数组有两种方法,一种方法是:

let arr:number[] = [1,2,3];

第二种方法是:

let list: Array<number> = [1, 2, 3];

Tuple(元组)

这个在JavaScript中是没有的,这个元组类型允许表示一个一直元素数量和类型的数组,个元素的类型不必相同。

例如:

// 定义元组
let x: [string, number];
//给元组里面的元素进行赋值
x = ['hello', 10]; // OK
// 错误示范
x = [10, 'hello']; // 报错
//当访问一个已知索引的元素,会得到

// 正确的类型:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 

'number' does not have 'substr'
//当访问一个越界的元素,会使用联合类型替代:
x[3] = 'world'; 

// OK, 字符串可以赋值给(string | number)类型
console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toString
x[6] = true; // Error, 布尔不是(string | number)类型

enum(枚举)

枚举类型是对JavaScript标准数据类型的一个补充。像C#等其他语言一样,使用枚举类型可以为一组数值赋予友好的名字。

例如:

//定义枚举
enum backgroundColor {Red,Pink,Black,Blue,Green}
//调用
let bc:backgroundColor = backgroundColor.Pink

默认情况下,从0开始为元素编号。手动的指定成员的赋值开始的编号,也可以手动的随意指定成员编号值。

例如:

//定义枚举
enum backgroundColor {Red=1,Pink=2,Black,Blue,Green}
//调用
let bc:backgroundColor = backgroundColor.Pink
//定义枚举,混合手动指定编号
enum backgroundColor {Red=1,Pink=2,Black=4,Blue=3,Green=6}
//调用
let bc:backgroundColor = backgroundColor.Pink
//这样的获取
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName);  // 显示'Green'因为上面代码里它的值是2

Any(交给编译阶段的检查)

这个就是将你需要检查的代码及数据交给编译阶段的时候进行自行检查,我们就可以使用any类型来标记这些变量。

例:

//定义
let notSure: any = 4;
//赋值
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

在对现有代码进行改写的时候,any类型是十分有用的,他允许你在编译时可选择的包含或一处类型检查。你可能认为object 有相似的作用,就像它在其他语言中那样。但是object类型的变量只是允许你给他赋任意值,但是却不能够在他上面调用任意的方法,即便他真的有这些方法。

例如:

let notSure: any = 4;
notSure.ifItExists(); 

// okay,
notSure.toFixed(); // okay,

let prettySure: Object = 4;
prettySure.toFixed(); //报错   还会报类型错误

//当你只知道一部分数据的类型时,any类型也是有用的
let list: any[] = [1, true, "free"];
list[1] = 100;

void(无返回值)

某种程度上来说,void类型像是与any类型相反,他表示没有任何类型。当一个函数没有返回值时,你通常会见到其返回值类型是void。

例如:

function warnUser(): void {
    console.log("This is my warning message");
}
//声明一个viod类型的变量没有什么大用,因为你只能为他赋予undefined和null;
let unvoid: void = undefined;

Null和Undefined

TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大。

let u: undefined = undefined;
let n: null = null;

默认情况下null和undefined是所有类型的子类型,就是说你可以把null和undefined赋值为别的数据类型的变量的。

Never(永远不存在的值得类型)

never类型表示的是那些永不存在的值的类型。never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。

例如:

// 返回never的函数必须存在无法达到的终点
function error(message: string){
	never {
    	throw new Error(message);
	}
}

// 推断的返回值类型为never
function fail() {
    return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(){
	never {
    	while (true) {
    	}
}

Object(对象)

object表示非原始类型,也就是除number(数字),string(字符串),boolean(布尔),symbol(符号),null或undefined之外的类型。使用object类型,就可以更好的表示像Object.create这样的API.

例如:

declare function 

create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK
create(42); // Error

类型断言

通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。
类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是
在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。
当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。
有两种形式,第一种是<>语法:

例如:

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

第二种是as的方法,例如:

let someValue: any = "this is a string";

let strLength: 
number = (someValue as string).length;

声明变量和常量

在JavaScript里面定义变量和常量的关键字是一样的。
定义变量的关键字是var和let。

他们的区别就是:
var定义的变量可能会被别的方法使用给调用的使用,然后有一个弊端就是会出现一个变量的全局污染。var定义的变量他会变量提前然后会程序没有到定义变量的那一行的时候会出现给其变量给赋undefined值。

let声明变量

  • let声明的变量不会挂在window中,不会造成全局变量的污染。
  • 新增了一个块级作用域{},以前只有函数作用域,全局作用域。
  • let是不允许重复声明
  • let不会有声明提前(只是人为看到的效果,实际上是有声明提前,提前临时性的死区中:Cannot access ‘num’ before initialization)

const声明常量

  • 跟let完全相同 增加几个点
  • 不允许被修改(不允许改变内存空间的地址)
  • const声明和赋值必须一次性完成,并且后期不允许改变存储空间的地址

函数

TypeScript里面定义函数的方法和JavaScript里面定义函数的方法是差不多的,同样也是可以使用ES6里面的箭头函数的。
正常定义函数的语法:

//常规定义函数的语法
function add(x, y) {
    return x + y;
}
let myAdd = function(x, y) { return x + y; 

};
//TypeScript定义完整的函数的语法
function add(x: number, y: number): number {
    return x + y;
}
let myAdd = function(x: number, y: number): number { return x + y; };

还可以这样用:

//函数完整的类型
let myAdd: (x: number, y: number) => number =function(x: number, y: number): number { return x + y; };
//另外的一种写法
let myAdd: (baseValue: number, increment: number) => number =
    function(x: number, y: number): number { 
    	return x + y; 
	};

可选参数和默认参数

注意:编译器还会假设只有这些参数会被传递进函数。简短地说,传递给一个函数的参数个数必须与函数期望的参数个数一致。

例如:

function buildName

(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // 报错,参数不足
let result2 = buildName("Bob", "Adams", 

"Sr.");  //报错,参数不足
let result3 = buildName("Bob", "Adams");         // ah, just right

JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。

在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。 比如,我们想让last name是可选的。

例如:

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");  //选着的参数
let result2 = buildName("Bob", "Adams", "Sr.");  

// 报错,参数过多
let result3 = buildName("Bob", "Adams");  // ah, just right

还有在es6中的 … 运算符使用也是一样的,例如:

function buildName(firstName: string, ...restOfName: string[]) {
  return firstName + " " + restOfName.join(" ");
}

let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;

注意事项

  • 这个里面的错误示范,如果在vscode软件上面的.ts文件里面书写他会直接报错的,不需要你运行就会给你提示出来的。
  • 在这里的let的使用和var的差不多,只是在这里使用let定义变量的是让我们熟悉的使用ES6里面的语法,在ES6里面出现了两个一个是let再就是const(常量)
  • 在TypeScript里面定义函数的方法和JavaScript里面定义函数的方法是一样的,同样也可以使用ES6里面的一些语法,也可以这么说在TypeScript里面定义函数是在JavaScript上提升了一些新的内容。
  • function pickCard(x): any并不是重载列表的一部分,因此这里只有两个重载:一个是接收对象另一个接收数字。 以其它参数调用 pickCard会产生错误。

后续会持续更新关于TypeScript的相应内容…

你可能感兴趣的:(typescript,javascript)