typescript入门和typescript面向对象入门

前言

typescript(以下简称ts)是微软开发、google(Angular2)支持的 js超集(增加面向对象编程的特性和某些ES6语法特性),任何js都可以不经修改的在ts环境下运行。很多著名的项目都已经将ts作为了开发语言,例如,我国的HTML5游戏引擎Egret、我国的前端样式库Ant-desgin等。总之,ts绝对代表了未来的大前端语言趋势,不学就落后了。

ts环境开发

一般情况下,可以在babel或者ts的在线练习环境来快速体验ts语言。但是,为了做项目,还是需要在本地安装好开发环境的,接下来,我们就看看如何在本地配置开发环境和IDE的。

安装compiler

npm i -g typescript
tsc --version
// 新建一个test.ts文件
export class testTS {

}
tsc test.ts --->编译--->test.js

"use strict";
exports.__esModule = true;
var testTS = /** @class */ (function () {
    function testTS() {
    }
    return testTS;
}());
exports.testTS = testTS;

与vscode进行集成

tsc --init // 创建tsconfig.json

有了tsconfig.json文件后,就可以对文件进行配置,设置好js文件夹和ts文件夹。

编译ts文件

使用vscode编译ts文件非常的方便,只需要run task即可。

run task

run task后会出现tsc:build 、tsc:watch两个选项,tsc:build是快速编译,tsc:watch是实时、监控编译,编译好后,文件就会存在于在tsconfig.json指定好的目录下了。

前端工程比较庞大的时候,或者需要将多个ts输出到多个js文件夹下的时候,建议使用webpack、gulp或者grunt来进行项目的打包和编译。这几个工具都是前端工程化的工具,在此不做一一展开来讲了。

简单学学ts语法

ts语法很多也是es6语法,因此,简单说说一些ts语法,全当对es6进行复习了。

字符串特性

多行字符串

使用``

字符串模板

使用`${xxx}`

自动拆分字符串

下图,test函数可以通过字符串模板来调用参数,就是后边的这些,可以用字符串模板调用,然后,自动拆分


自动拆分字符串之函数调用
自动拆分字符串之结果展示

参数

指定参数类型

使用【冒号 = :】来指定变量、参数、函数返回值类型,并且,类型具有推断机制,如果给string类型的变量,赋值数字的话,IDE会报错。(这里也仅仅是IDE会报错,因此,js是动态语言,不存在类型的概念,通过ts转换为js不管怎么说都是对的)

另外,通过类的概念自定类型后,自定义的类型也可以作为普通类型使用

var nymm:string='11111dssasd'
var nymm:any='11111dssasd'
var nymm:number='11111dssasd'
var nymm:boolean='11111dssasd'

// 可选参数,b就是可选参数,可以不传递
function test(er:string,ki:string = "ddd",op?:string):void{

}

// 自定义类型

class Car {
    name:string;
    logo:string
}

var ben:Car = new Car();

默认参数与可选参数

给参数赋默认值,如果有普通参数,那么,默认参数不可以为第一个参数,否则,在赋值的时候,会对参数的赋值进行覆盖。同时,还提供了【问号 = ?】来指定其为可选参数,并且,可选参数必须放在必选参数之后。

function test(er:string,ki:string = "ddd",op?:string):void{

}

函数

Rest and Spread操作符

Rest and Spread操作符,例如【...args】,这个操作符表示可以声明任意数量的方法参数。这个参数表示的是一个数组,调用该参数的时候,要按照数字的方式进行处理。

// 任意长度参数定义
function fun(...args){}

// 定长参数定义
function fun2(a,b,c)
var ays = [1,2,9]

// 定长函数调用
fun2(...ays)

generator和async函数操纵顺序程序

generator以及async函数,都是promise的语法糖。用来控制函数的执行过程,通过yield和await来控制代码的执行。配合着next(),来控制顺序程序的暂停和开启。然后,每次,调用next(),都会停在某一个yield或者async。

图片.png

对于异步函数,其实就是promise的返回,因此,直接操作返回的对象即可。

析构表达式(destructuring)

通过表达式将对象或数组拆解成任意数量的变量

拆解对象

拆解对象

拆解数组

拆解数组跳过数据
拆解数组 + Rest and Spread操作符

箭头表达式

用来声明匿名函数,消除传统匿名函数的this指针问题,因为,js中的this关键字,会发生js指向和预期指向不一致的情况。因为,this的指向是调用自己的函数的指向,但是,因为闭包、函数嵌套调用等原因,this的指向会发生改变。通过箭头表达式,将this指向了最外层的函数,从而,让一个函数内共享了this内存,从而解决指向改变的问题。

最简单的匿名函数

var kill = (bill,kate)=>bill + kate;

等价于

var kill = function (bill,kate) {return bill + kate};

this指向发生改变的一种情况

例如,上图的情况,this指向了匿名函数,因此会打印不出值。

this指向发生改变的一种情况的实际数据打印

对于非箭头函数表达式下的this的简单说明

在普通函数中,this指代的是调用他的函数,例如

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

这个函数打印的就不是一个值,因为,foo是引用,因此是全局环境下的对象对于this的调用,因此,值是不一样的。

当然,关于this,很有必要单独开一个文章来讲解

循环

本节将要讲解forEach()、for in、for of循环的异同

forEach()

forEach(),有两个特性,第一是不能break跳出,第二是会忽略对象的展示。

forEach()
忽略对象的展示

for in

for in循环的是keys,同时可以使用break跳出。

for of

for of循环的是values,同时可以使用break跳出。

面向对象

ts的面向对象,或者说js的面向对象与c++或者java很不一样。因为这种解释型的语言,本身就已经是对象了,因此,在操纵内存的时候要格外小心。

Class

ts要求使用面向对象的特性来书写程序,既然是面向对象,那么,就可以更好的利用继承、封装和多态了。使用面向对象,可以更好的实现抽象定义和整个程序的架构。

定义

类的定义

我们可以看到es5下,类的定义是基于匿名函数和闭包的,同时还提供了prototype这个属性。在此不做展开,大家自行查阅资料。(此处涉及到匿名函数的调用和原型链的知识,此处建议学习v8引擎的相关说明资料https://v8.dev/docs和ECMAScript的说明文档https://tc39.es/ecma262/#sec-ecmascript-specification-types

另外,对于上边的代码,特别要注意的是,在es5下,匿名函数一定要自执行后,才能调用,因为,在没有执行前,匿名函数没有意义。

访问控制符

默认的访问控制符是public,同时还可以添加private和protected。public表示都可以访问,private表示内部访问,protected表示内部包或者子类可以访问。

构造函数(constructor())

构造函数

构造函数的参数,一定要显式的做访问控制符的声明,否则需要在外部单独指定其访问控制权限。

继承(extends和super)

如果我们用es5来实现class和extends语法糖的话,那么就应该是这样的几个函数,此处又涉及到多个问题,因此,之后会专门开个文章系列来讨论这部分内容。另外,通过查看es5的实现方式,我们也明白了,extends和super的意义。

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Animal = /** @class */ (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 0; }
        console.log(this.name + " moved " + distanceInMeters + "m.");
    };
    return Animal;
}());
var Snake = /** @class */ (function (_super) {
    __extends(Snake, _super);
    function Snake(name) {
        return _super.call(this, name) || this;
    }
    Snake.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 5; }
        console.log("Slithering...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Snake;
}(Animal));
var Horse = /** @class */ (function (_super) {
    __extends(Horse, _super);
    function Horse(name) {
        return _super.call(this, name) || this;
    }
    Horse.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 45; }
        console.log("Galloping...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Horse;
}(Animal));
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);

泛型(generic)

参数化的类型,一般用来限制集合的内容。换句话说,就是声明某个集合必须是什么数据类型。

var workers:Array<Worker>  = []

这个数组就要求,我们只能将worker放到数组中。

接口(interface)

用来建立某种代码约定,使得其他开发者在调用某个方法或者创建新的类时必须遵循接口所定义的代码约定。使用interface定义,使用implements引用。

定义接口并使用

定义接口并使用

基于implements实现接口

基于implements实现接口

模块(Module)

在ts或者js中,一个文件,其实就是一个模块,通过export和import进行模块的导出和导入。

模块可以帮助开发者将代码分割为可重用的单元。开发者可以自己决定将模块中的哪些资源(类、方法、变量)暴露出去供外部使用,哪些资源只在模块内部使用。

值得注意的是,对于继承来说,因为,类肯定也是在不同模块中的,因此,我们既要将模块import,还要extends对应的类。(此处要注意CommonJS(CMD、AMD)和es6模块的异同)

注解(annotation)

注解为程序的元素(类、方法、变量)加上更加直观的说明,这些说明信息与程序的业务逻辑无关,只是供指定的工具或者框架使用。(关于注解,可以具体查看相关工具的文档)

类型定义文件(*.d.ts)

ts想要使用js工具包已有的程序应该怎么办呢?之前以及说过了,js可以不经修改的在ts下执行,那么,我们其实可以直接调用js,但是,又存在语法差异,不免会产生bug,因此,使用类型定义文件来帮助ts调用js的已有代码,放在bug的产生。例如:koa等

类型定义文件,来源于DefinitelyTyped项目https://github.com/DefinitelyTyped/DefinitelyTyped

例如koa的类型定义文件就是在这个下边https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa/index.d.ts,通过 npm i @types/koa便可以安装这个项目,也可以通过typings来安装和查找。这个项目中,有大量的已有js项目的类型定义文件。

注意,其实还可以通过通过typings(https://github.com/typings/typings)来寻找以及存在的类型定义文件。但是,由于官方推荐 NPM @types的形式来安装类型定义文件,因此,可以不去安装typings了,直接使用npm的安装方式即可。

npm WARN deprecated typings@2.1.1: Typings is deprecated in favor of NPM @types -- see README for more information
npm WARN deprecated popsicle-proxy-agent@3.0.0: Use `agent` option with `popsicle` directly

npm i typings -g
typings search --name project_name
typings install project_name --save

后记

本文概要的讲解了ts和ts的面向对象,对于很多知识都没有展开来讲,例如,es5为什么要那样构建类,class、extends等语法糖的es5版本为啥要那样写,注解如何使用等等。

对于此部分的内容,我将会在后续的专题中,深入讨论的。

讨论一下ts做后端开发

对于使用过Java、PHP、C#等开发后端的程序员来说,ts语法会让你们感到更加的亲切。但是,因为,ts本身还在发展,因此,例如装饰器、注解等还是需要第三方库进行支持。

Routing-controllers库

https://github.com/typestack/routing-controllers

该库为express、koa添加了装饰器模式,可以通过注解的方式来操控web服务器。

TypeDI依赖注入库

https://github.com/pleerock/typedi

TypeORM

https://github.com/typeorm/typeorm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容