TypeScript 基础
介绍
以下文字摘自官网
TypeScript is a typed superseet of JavaScript that compiles to plain JavaScript, Any browser, Any host. Any OS. Open source.
还有一句话
JavaScript that scales.
大致翻译是说:TypeScript 是 JavaScript 的一个带类型的超集,可以编译成JavaScript。
JavaScript
介绍中提到,TypeScript可以编译成JavaScript。事实上,根本没有一个解释器可以直接执行TypeScript,如果要想执行它,当须先编译成JavaScript方可。这也说明,如果想用好TypeScript,是需要有JavaScript基础的,事实上使用TypeScript的人,基本上都是JavaScript转过来的。至于为什么弃J从T,当由JavaScript的不足说起。
优点
-
浏览器原生支持
现今没有一款浏览器不支持JavaScript的,虽然有禁用JavaScript一项设置,但几乎不会有人进行这样的禁用设置。展望将来,也能预见,不会有浏览器会停止支持JavaScript。也就是说,在浏览器里面,如果要写脚本,首选就是JavaScript。
-
简单
包括语言易学(至少入门级的如此),开发调试方便。你所需要的只是一个几乎脑脑必备的浏览器+任意一款文本编辑器(甚至没有文本编译器也可以),无须复杂的环境安装和配置。
-
弱类型
这是语言特性,弱类型使用简单,更灵活多变。
缺点
-
弱类型
前面提到,这是JavaScript的一项优点,但它是一个双刃剑,更是一个大大的缺点,因为是弱类型,在进行编译的时候,弱类型会影响编译优化(所以我们在编写JavaScript代码的时候,尽量不要让一个变量一会儿是数字类型,一会儿是字符串类型)。因为弱类型,使得无法方便地通过查看代码确定一个变量的类型,这在代码维护上带来了无穷无尽的麻烦,有些前人的代码,简直惨不忍睹(其实别人看你的代码没准儿也是这感觉)。这给我们的感觉就是无法通过JavaScript做大的软件项目,因为软件项目大到一定量的时候就无法继续维护下去了。
-
异步回调
因为JavaScript的事件驱动机制,会有大量的回调函数,如果回调函数里再嵌套的有其它的回调函数,一层层的回调函数调下去,就到了回调地狱,如果你曾有过此等遭遇,那么恭喜你,因为你这时才能更深刻理解Promise和Async functions!很多人因此离开了JavaScript。
-
不能操作本地资源
在浏览器里,JavaScript能做的事情非常有限,只能操作页面上的Dom元素,响应用户的鼠标或键盘事件。很多事情类似操作本地磁盘上的一个Word文档等做起来都很吃力,甚至产生了一系列的“浏览器插件”来完成这样的一些功能(很不幸地,这些插件还需要限定特定的浏览器)。
-
this
JavaScript中的
this
跟其它开发语言中不太一样,很多有多年开发经验的人员一直搞不清楚JavaScript中的this
是个什么东西。它竟然是可变的,这简直太恐怖了!
解决方案
如何在保留JavaScript优点的基础上弥补一下它的缺点?弃而投靠其它开发语言不是一个好的解决办法,那样你会遇到另外其它的问题。
解决方案:Node.js+TypeScript+Function,其中Node.js(包括nw.js,electron)用来让JavaScript具有操作本地资源的能力。TypeScript让复杂项目变得可维护,用它来做复杂项目变为可能。只使用函数(如果是回调,则使用箭头函数)而不使用类
,使我们几乎不用关心this
的问题。
认识TypeScript
进入正题,我们来看一下TypeScript的代码:
function sayhi(name: string) {
console.log(`hi, ${name}!`);
}
上面的三行代码声明了一个函数
,函数名为sayhi
,这个函数有一个参数,形参名字为name
,形参的类型为string
.这个函数没有返回值。如果我们调用了该函数,像这样:
sayhi('feidao');
它会在控制输出一行文字:hi, feidao!
;
变量
声明一个变量的关键字为let
,声明变量的同时可以给它赋上初始值。如下所示
let v = 1;
++v;
常量
声明一个常量的关键字const
,事实上TypeScript中的const
并非一定的常量,它仍然可以改变。比如引用类型的jsObject或是jsArray都可以改变,它只是不能被重新赋值罢了。
const v = 1;
++v; // Error: Cannot assign to 'v' because it is a constant or a read-only property.
const arr = [1, 2, 3];
arr.push(4); // 没有错误,可以正常使用
注意看以上两种情形,第一种情况因为有自增运算++
,包括前自增,在JavaScript里它都属于重新赋值,所以TypeScript编译器会对这些已经声明过为常量对象进行重新赋值的代码行报错,赋值的操作还包括=
,+=
,-=
,*=
,/=
,|=
,^=
,>>=
,<<=
等。
const
声明的常量与Object.freeze
有相近之处,都是希望它们不能被改变,只不过它们的差别是const
声明的常量如果是Object
,包括Array
,虽然不能被重新赋值,但实际上还是可以修改的,而Object.freeze
正是针对Object
类型的。
个人建议全部用const
声明常量,从来不要用let
,甚至var
声明变量。甚至如果有必要,对const
声明的Object
类型的常量再加以Object.freeze
限定就更好了。
接口
接口在强类型开发语言中,接口是指实体把自己提供给外界的一种抽象化物,由一套陈述、功能、选项、其它表达程序结构的形式、以及程序师使用的程序或者程序语言提供的数据组成。它通常用于一些类
去实现接口中定义的一些方法,在TypeScript中,我们也可以这么干,但接口对我们来讲,主要用来定义一些数据结构。像前面最开始的示例
function sayhi(name: string) {
console.log(`hi, ${name}!`);
}
如果我们把它修改一下,就用到了接口:
interface Person {
name: string;
age: number;
}
function sayhi(person: Person) {
console.log(`hi, ${person.name}! your are ${persoon.age} years old.`);
}
我们在例子中定义的接口,它的主要使用就是给这个函数的调用者一个调用参数的类型限定。我们在调用这个函数的时候就需要像下面这样调用它
sayhi({name:'feidao', age: 5});
它不仅用来定义函数的参数类型,有时候我们也用它来定义函数的返回值类型
function fun(name: string, age: number) {
return {
age,
name
};
}
类
TypeScript中的类跟Java,C#中的类几乎一模一样。如果你有这方面的编程经验,这一部分可以跳过了。
我们这里对TypeScript中的类做一个介绍,但我们在项目开发过程中基本是不会写类,我们在项目中只写函数,但我们可能会用到类,比如Date,所以我们简单介绍一下,做个了解就好,只要会使用就足够了。
声明
声明一个简单的类,它的名字叫A
,并且有一个受保护的方法,名字叫method_a
class A {
protected method_a() {
// todo
}
}
一个类都有构造函数constructor
(原谅我用构造函数而没有用构造方法这个词,因为大家似乎都这么叫),但有些时候我们不写构造函数,像上例一样,其实它还是有构造函数的,只是你看不到罢了:
class A {
constructor() {
}
protected method_a() {
// todo
}
}
但它没有析构函数,GC
会帮我们回收不用的内存资源。
接下来我们来从它派生一个类,名字叫B,它有一个公有方法叫method_b
.
class B extends A {
constructor(param: string) {
super();
}
public method_b() {
this.method_a();
}
}
在B的所有方法里,我们都可以调用A的所有受保护protected
以及公开public
的方法。需要通过this
来调用。
使用
使用一个类的时候,我们需要先将这个类构造出来一个对象
,然后使用这个对象
调用它的成员函数
或成员变量
。
const a = new A();
a.method_a(); // ts error, but it could be called indeed.
const b = new B('lalala');
b.method_b();
注意一定不要将一个类的成员函数当作回调函数去调用,因为这会改变this
。如
const b = new B();
setInterval(b.method_b, 2000); // Dot not use like this
如果遇到这种情况,要这么用它:
const b = new B();
setInterval(() => {
b.method_b(); // Use like this
}, 2000);
其它
诸如派生接口、静态方法等知识,因为我们极少使用,为了减轻大家的学习负担,不在这里介绍,如果有兴趣,请稳步各大搜索引擎.