精通系列)(我的第一个TS程序)WebStorm版本

Posted 蓝盒子itbluebox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精通系列)(我的第一个TS程序)WebStorm版本相关的知识,希望对你有一定的参考价值。

源代码:https://download.csdn.net/download/qq_44757034/86504095

TypeScript 快速入门(一篇文章精通系列)(我的第一个TS程序【一】)【WebStorm版本】

1、初识TypeScript


TypeScript的介绍

TypeScript是一种由微软开发的开源、跨平台的编程语言。它是javascript的超集,最终会被编译为JavaScript代码。

2012年10月,微软发布了首个公开版本的TypeScript,

2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript

TypeScript的作者是安德斯·海尔斯伯格,C#的首席架构师。

它是开源和跨平台的编程语言。

TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以运行在TypeScript环境中。

TypeScript的特点

TypeScript主要有3大特点:。始于JavaScript,归于JavaScript

TypeScript 可以编译出纯净

简洁的JavaScript 代码,并且可以运行在任何浏览器上、Node.js环境中和任何支持ECMAScript 3(或更高版本)的JavaScript引擎中。

强大的类型系统

类型系统允许JavaScript开发者在开发JavaScript应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。

先进的JavaScript

TypeScript提供最新的和不断发展的JavaScript特性,包括那些来自2015 年的ECMAScript和未来的提案中的特性,比如异步功能和Decorators,以帮助建立健壮的组件。

总结
TypeScript 在社区的流行度越来越高,它非常适用于一些大型项目,也非常适用于一些基础库,极大地帮助我们提升了开发效率和体验。

2、安装TypeScript

命令行运行如下命令,全局安装TypeScript:

npm install -g typescript


安装完成后,在控制台运行如下命令,检查安装是否成功(3.x):

tsc -v

3、编写第一个TypeScript程序

(1)编写TS程序




function greeter (person) 
    return 'Hello, ' + person

let user = 'Yee'
console.log(greeter(user))


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--直接引入了ts文件,浏览器就会报错(如果ts文件当中只有单纯的js的语法代码是可以正常运行的,如果有ts的语法直接打开浏览器是无法运行的)-->
<script src="./firstTs.ts" ></script>
</body>
</html>

直接引入了ts文件,浏览器就会报错(如果ts文件当中只有单纯的js的语法代码是可以正常运行的,如果有ts的语法直接打开浏览器是无法运行的)

(2)手动编译代码

我们使用了 .ts 扩展名,但是这段代码仅仅是 JavaScript 而已。

在命令行上,运行 TypeScript 编译器:



刷新页面

我们也可以使用node来运行

node firstTs.js

(3)WebStorm自动编译




$FileNameWithoutExtension$.js:$FileNameWithoutExtension$.js.map
$FileDir$



编写ts代码自动生成js

4、类型注解

接下来让我们看看 TypeScript 工具带来的高级功能。
给 person 函数的参数添加 : string 类型注解,如下:

function greeter(person:string)
    return 'hello'+person

let user = '床前明月光,疑是地上霜'
console.log(greeter(user))


运行成功

设置user为其他类型

ts文件报错

js文件编译后不报错

打开网页显示正常

5、接口

让我们继续扩展这个示例应用。这里我们使用接口来描述一个拥有 firstName 和 lastName 字段的对象。

在 TypeScript 里,只在两个类型内部的结构兼容,那么这两个类型就是兼容的。

这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地使用 implements 语句。


//接口:是一种能力或者约束
//定义接口
interface IPerson
    firstName: string //姓氏
    lastName: string //名字

//输出姓名
function showFullName(person: IPerson)
    return person.firstName + "_" + person.lastName

const person =
    firstName:"采菊东篱下",
    lastName: "悠然见南山"

console.log(showFullName(person))



将person当中的一部分注释掉


打开页面

6、类

(1)创建类

最后,让我们使用类来改写这个例子。 TypeScript 支持 JavaScript 的新特性,比如支持基于类的面向对象编程。

让我们创建一个 User 类,它带有一个构造函数和一些公共字段。因为类的字段包含了接口所需要的字段,所以他们能很好的兼容。

还要注意的是,我在类的声明上会注明所有的成员变量,这样比较一目了然。



interface IPerson
    firstName:string, //姓氏
    lastName:string //名字

//定义一个类型
class Person
    //定义一个公共的字段
    firstName:string    //姓氏
    lastName:string     //名字
    fullName:string     //姓名、
    //定义一个构造器函数(constructor)
    constructor(firstName:string,lastName:string,fullName:string) 
        //更新属性数据
        this.firstName = firstName
        this.lastName = lastName
        //姓名
        this.fullName = this.firstName + '_' + this.lastName
    
    //定义get方法用于获取对应类的内置属性
    greet() : string
        return "Hello "+this.fullName
    
    //定义set方法用于设置类的一些属性
    set(firstName:string,lastName:string)
        this.firstName = firstName
        this.lastName = lastName
        //姓名
        this.fullName = this.firstName + '_' + this.lastName
    

//实例化对象
const person = new Person("诸葛","孔明","诸葛孔明")
console.log(person.greet())
person.set("赵","子龙")

console.log(person.greet())

运行测试


如果你使用过 C#Java,你会对这种语法非常熟悉。 我们声明一个 Greeter 类。
这个类有 3 个成员:

一个叫做 message 的属性,
一个构造函数
一个 greet 方法。
一个 set 方法

你会注意到,我们在引用任何一个类成员的时候都用了 this。
它表示我们访问的是类的成员。

后面一行,我们使用 new 构造了 Greeter 类的一个实例。
它会调用之前定义的构造函数,创建一个 Greeter 类型的新对象,并执行构造函数初始化它。

最后一行通过 greeter 对象调用其 greet 方法

(2)类的继承



class Animal
    run(distance:number)
        console.log(`Animal run $distancem`)
    


class Dog extends Animal
    cry()
        console.log("wang! wang!")
    


const dog = new Dog();

dog.cry()
dog.run(100)

<script src="./ClassTestExtends.js" ></script>


这个例子展示了最基本的继承:类从基类中继承了属性和方法。

这里,Dog 是一个 派生类,它派生自 Animal 基类,通过 extends 关键字。

派生类通常被称作子类,基类通常被称作超类。

因为 Dog 继承了 Animal 的功能,因此我们可以创建一个 Dog 的实例,它能够 cry() 和 run()。

(3)类使用的案例

class Animal 
    name: string

    constructor (name: string) 
        this.name = name
    

    run (distance: number=0) 
        console.log(`$this.name run $distancem`)
    



class Snake extends Animal 
    constructor (name: string) 
        // 调用父类型构造方法
        super(name)
    

    // 重写父类型的方法
    run (distance: number=5) 
        console.log('sliding...')
        super.run(distance)
    


class Horse extends Animal 
    constructor (name: string) 
        // 调用父类型构造方法
        super(name)
    

    // 重写父类型的方法
    run (distance: number=50) 
        console.log('dashing...')
        // 调用父类型的一般方法
        super.run(distance)
    

    xxx () 
        console.log('xxx()')
    


const snake = new Snake('sn')
snake.run()

const horse = new Horse('ho')
horse.run()

// 父类型引用指向子类型的实例 ==> 多态
const tom: Animal = new Horse('ho22')
tom.run()

/* 如果子类型没有扩展的方法, 可以让子类型引用指向父类型的实例 */
const tom3: Snake = new Animal('tom3')
tom3.run()

/* 如果子类型有扩展的方法, 不能让子类型引用指向父类型的实例 */
const tom2: Animal = new Animal('tom2')
tom2.run()


这个例子展示了一些上面没有提到的特性。 这一次,我们使用 extends 关键字创建了 Animal的两个子类:Horse 和 Snake。

与前一个例子的不同点是,派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数。 而且,在构造函数里访问 this 的属性之前,我们 一定要调用 super()。

这个是 TypeScript 强制执行的一条重要规则。

这个例子演示了如何在子类里可以重写父类的方法。

Snake类和 Horse 类都创建了 run 方法,它们重写了从 Animal 继承来的 run 方法,
使得 run 方法根据不同的类而具有不同的功能。

注意,即使 tom 被声明为 Animal 类型,但因为它的值是 Horse,调用 tom.run(34) 时,
它会调用 Horse 里重写的方法。

7、公共,私有与受保护的修饰符

默认为 public

在上面的例子里,我们可以自由的访问程序里定义的成员。

如果你对其它语言中的类比较了解,就会注意到我们在之前的代码里并没有使用 public 来做修饰;

例如,Java要求必须明确地使用 public 指定成员是可见的。

在 TypeScript 里,成员都默认为 public。

你也可以明确的将一个成员标记成 public。 我们可以用下面的方式来重写上面的 Animal 类:

理解 private

当成员被标记成 private 时,它就不能在声明它的类的外部访问。

理解 protected

protected 修饰符与 private 修饰符的行为很相似,但有一点不同,protected成员在派生类中仍然可以访问。例如:

访问修饰符: 用来描述类内部的属性/方法的可访问性
public: 默认值, 公开的外部也可以访问
private: 只能类内部可以访问(子类和外部类都不可以访问)
protected: 类内部和子类可以访问(外部不可以访问但是子类可以访问)


class Animal 
    public name: string

    public constructor (name: string) 
        this.name = name
    

    public run (distance: number=0) 
        console.log(`$this.name run $distancem`)
    


class Person extends Animal 
    private age: number = 18
    protected sex: string = '男'

    run (distance: number=5) 
        console.log('Person jumping...')
        super.run(distance)
    


class Student extends Person 
    run (distance: number=6) 
        console.log('Student jumping...')

        console.log(this.sex) // 子类能看到父类中受保护的成员
        // console.log(this.age) //  子类看不到父类中私有的成员

        super.run(distance)
    


console.log(new Person('abc').name) // 公开的可见
console.log(new Person('abc').sex) // 受保护的不可见
console.log(new Person('abc').age) //  私有的不可见

8、readonly 修饰符

你可以使用 readonly 关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。

/*
访问修饰符: 用来描述类内部的属性/方法的可访问性
  public: 默认值, 公开的外部也可以访问
  private: 只能类内部可以访问(子类和外部类都不可以访问)
  protected: 类内部和子类可以访问(外部不可以访问但是子类可以访问)
*/

class Person 
    readonly name: string = 'abc'
    constructor(name: string) 
        this.name = name
    
    getter ()
        return this.name
    


let john = new Person('John')
john.name = '张三'

9、参数属性

在上面的例子中,我们必须在 Person 类里定义一个只读成员 name 和一个参数为 name 的构造函数,并且立刻将 name 的值赋给 this.name,这种情况经常会遇到。
参数属性可以方便地让我们在一个地方定义并初始化一个成员。 下面的例子是对之前 Person 类的修改版,使用了参数属性:

class Person2 
    constructor(readonly name: string) 
    


const p = new Person2('jack')
console.log(p.name)


注意看我们是如何舍弃参数 name,仅在构造函数里使用 readonly name: string 参数来创建和初始化 name 成员。 我们把声明和赋值合并至一处。

参数属性通过给构造函数参数前面添加一个访问限定符来声明。使用 private 限定一个参数属性会声明并初始化一个私有成员;对于 public 和 protected 来说也是一样。

10、存取器

TypeScript 支持通过 getters/setters 来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

下面来看如何把一个简单的类改写成使用 get 和 set。 首先,我们从一个没有使用存取器的例子开始。

class Person

    firstName:string = 'A'
    lastName:string = 'B'
    get fullName()
        return this.firstName + '-'+this.lastName
    
    set fullName(value)
        const names = value.split('-')
        this.firstName = names[0]
        this.lastName = names[1]
    

const p = new Person()

console.log(p.fullName)

p.firstName = 'C'
p.lastName = 'D'

console.log(p.fullName)

p.fullName = 'E-F'
console.log(p.firstName,p.lastName)

11、静态属性

到目前为止,我们只讨论了类的实例成员,那些仅当类被实例化的时候才会被初始化的属性。

我们也可以创建类的静态成员,这些属性存在于类本身上面而不是类的实例上。

在这个例子里,我们使用 static 定义 origin,因为它是所有网格都会用到的属性。

每个实例想要访问这个属性的时候,都要在 origin 前面加上类名。

如同在实例属性上使用 this.xxx 来访问属性一样,这里我们使用 Grid.xxx 来访问静态属性。

/* 
静态属性, 是类对象的属性
非静态属性, 是类的实例对象的属性
*/
class Person 
  name1: string = 'A'
  static name2: string = 'B'

console.log(Person.name2)
console.log(new Person().name1)


我们试图修改name2和name1的值

12、抽象类

抽象类做为其它派生类的基类使用。 它们不能被实例化。

不同于接口,抽象类可以包含成员的实现细节。

abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。

/*
抽象类
  不能创建实例对象, 只有实现类才能创建实例
  可以包含未实现的抽象方法
*/
abstract class Animal

    abstract cry()

    run()
        console.log('run()')
    


class Dog extends Animal
    cry() 
        console.log('Dog cry()')
    


var dog = new Dog();

dog.cry()
dog.run()

13、使用webpack打包TS

(1)创建相关文件











注意之前的自动编译的配置




const CleanWebpackPlugin = require('clean-webpack-plugin'精通系列)(我的第一个TS程序)WebStorm版本

精通系列)WebStorm版

精通系列)WebStorm版

精通系列)WebStorm版

精通系列)webpack(常用语法)WebStorm版本

精通系列)webpack(常用语法)WebStorm版本