TypeScript教程2
在TS中,我们允许开发人员使用面向对象技术。
1、类
让我们看看一个简单的基于类的例子:
- class Greeter {
- greeting: string;
- constructor(message: string) {
- this.greeting = message;
- }
- greet() {
- return "Hello, " + this.greeting;
- }
- }
- var greeter = new Greeter("world");
复制代码
语法应该非常熟悉,如果你以前使用c#或者Java或者AS。 我们声明一个新的类“Greeter”。 这个类有三个成员,即所谓的“greeting”,构造函数和方法“greet”。
在类中我们使用greeter.greeting的方式访问类属性。
在最后一行我们构造一个实例。 这回调用Greeter的constructor方法。
2、继承
在TS中,我们可以使用常见的面向对象模式。 当然,最基本的模式之一,就是扩展现有的类来创建新类。即继承。
让我们看一个例子:
- class Animal {
- name:string;
- constructor(theName: string) { this.name = theName; }
- move(meters: number) {
- alert(this.name + " moved " + meters + "m.");
- }
- }
- class Snake extends Animal {
- constructor(name: string) { super(name); }
- move() {
- alert("Slithering...");
- super.move(5);
- }
- }
- class Horse extends Animal {
- constructor(name: string) { super(name); }
- move() {
- alert("Galloping...");
- super.move(45);
- }
- }
- var sam = new Snake("Sammy the Python");
- var tom: Animal = new Horse("Tommy the Palomino");
- sam.move();
- tom.move(34);
复制代码
这个例子包括相当多的TS中的继承特性。 在这里,我们看到使用扩展的关键字来创建一个子类。 你可以看到这个“马”和“蛇”子类 类“动物”,获得其功能。
示例还展示了能够覆盖基类中的方法。 这里“蛇”和“马”创建一个移动的方法,覆盖了从“动物”“移动”。
3、私人/公共修饰符
您可能已经注意到在上面的例子中我们没有使用“public”这个词使任何成员的类可见。 c#等语言要求每个成员被显式地标记“public”是可见的。 在TS, 每个成员在默认情况下是公共的。
关于私有变量,我们可以这样写:
- class Animal {
- private name:string;
- constructor(theName: string) { this.name = theName; }
- move(meters: number) {
- alert(this.name + " moved " + meters + "m.");
- }
- }
复制代码
4、访问器
TS支持getter / setter的拦截访问一个对象的成员。 这可以控制如何访问每个对象成员。
让我们把一个简单的类,使用“getter ”和“setter”。 首先,让我们从一个示例开始没有getter和setter。
- class Employee {
- fullName: string;
- }
- var employee = new Employee();
- employee.fullName = "Bob Smith";
- if (employee.fullName) {
- alert(employee.fullName);
- }
复制代码
同时允许人们直接fullName随机设置很方便,如果我们人们可以随意改变名字,可能给我们带来麻烦。
在这个版本中,我们检查以确保用户有一个秘密的密码可用之前,我们让他们修改员工。 我们通过直接访问fullName替换的“setter”查看密码。 我们添加一个相应的“getter ” 让前面的示例无缝地继续工作。
- var passcode = "secret passcode";
- class Employee {
- private _fullName: string;
- get fullName(): string {
- return this._fullName;
- }
- set fullName(newName: string) {
- if (passcode && passcode == "secret passcode") {
- this._fullName = newName;
- }
- else {
- alert("Error: Unauthorized update of employee!");
- }
- }
- }
- var employee = new Employee();
- employee.fullName = "Bob Smith";
- if (employee.fullName) {
- alert(employee.fullName);
- }
复制代码
5、静态属性
到目前为止,我们只讨论了 实例成员,只有当实例化后才可以使用。 我们还可以创建 静态成员,那些不用实例化就可以使用的属性或者方法。
- class Grid {
- static origin = {x: 0, y: 0};
- calculateDistanceFromOrigin(point: {x: number; y: number;}) {
- var xDist = (point.x - Grid.origin.x);
- var yDist = (point.y - Grid.origin.y);
- return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
- }
- constructor (public scale: number) { }
- }
- var grid1 = new Grid(1.0); // 1x scalevar grid2 = new Grid(5.0); // 5x scale
- alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
- alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
复制代码
==================================================
在TS中使用模块通过各种方式组织代码。 我们将要涉及的内部和外部模块。并且讨论如何使用它们。
1、第一步
我们写一组简单的字符串验证器,像你可能使用时检查用户输入的表单在网页或检查外部提供的格式 数据文件。
验证器在一个单一的文件中
- interface StringValidator {
- isAcceptable(s: string): boolean;
- }
- var lettersRegexp = /^[A-Za-z]+$/;
- var numberRegexp = /^[0-9]+$/;
- class LettersOnlyValidator implements StringValidator {
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- // Some samples to tryvar strings = ['Hello', '98052', '101'];
- // Validators to usevar validators: { [s: string]: StringValidator; } = {};
- validators['ZIP code'] = new ZipCodeValidator();
- validators['Letters only'] = new LettersOnlyValidator();
- // Show whether each string passed each validator
- strings.forEach(s => {
- for (var name in validators) {
- console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
- }
- });
复制代码
2、添加模块
当我们添加更多的验证器,我们会想要组织起来,这样我们可以跟踪我们的类型,而不是担心与其他对象名称冲突。让我们将对象放到一个模块中。
模块化的验证器
- module Validation {
- export interface StringValidator {
- isAcceptable(s: string): boolean;
- }
- var lettersRegexp = /^[A-Za-z]+$/;
- var numberRegexp = /^[0-9]+$/;
- export class LettersOnlyValidator implements StringValidator {
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- export class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- }
- // Some samples to tryvar strings = ['Hello', '98052', '101'];
- // Validators to usevar validators: { [s: string]: Validation.StringValidator; } = {};
- validators['ZIP code'] = new Validation.ZipCodeValidator();
- validators['Letters only'] = new Validation.LettersOnlyValidator();
- // Show whether each string passed each validator
- strings.forEach(s => {
- for (var name in validators) {
- console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
- }
- });
复制代码
3、跨文件分割【常用】
随着应用程序的增长,我们需要将代码拆分为多个文件,让它更容易维护。
在这里,我们分开验证模块到多个文件。 即使文件是分开的,他们都能调用相同的模块。 因为有文件之间的依赖关系,我们 添加【/// <reference path="Validation.ts" />】引用标记来告诉编译器的文件之间的关系。 否则我们的测试代码不变。
多文件内部模块Validation.ts
- module Validation {
- export interface StringValidator {
- isAcceptable(s: string): boolean;
- }
- }
复制代码
LettersOnlyValidator.ts
- /// <reference path="Validation.ts" />
- module Validation {
- var lettersRegexp = /^[A-Za-z]+$/;
- export class LettersOnlyValidator implements StringValidator {
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- }
复制代码
ZipCodeValidator.ts
- /// <reference path="Validation.ts" />
- module Validation {
- var numberRegexp = /^[0-9]+$/;
- export class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- }
复制代码
Test.ts
- /// <reference path="Validation.ts" />/// <reference path="LettersOnlyValidator.ts" />/// <reference path="ZipCodeValidator.ts" />
- // Some samples to tryvar strings = ['Hello', '98052', '101'];
- // Validators to usevar validators: { [s: string]: Validation.StringValidator; } = {};
- validators['ZIP code'] = new Validation.ZipCodeValidator();
- validators['Letters only'] = new Validation.LettersOnlyValidator();
- // Show whether each string passed each validator
- strings.forEach(s => {
- for (var name in validators) {
- console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
- }
- });
复制代码
有多个文件后,我们需要确保所有的编译后的代码被加载。 这样做有两种方式。
首先,我们可以使用连接输出使用 ——编译所有的输入输出文件到一个单独的JavaScript文件:
- tsc --out sample.js Test.ts
复制代码
编译器会自动顺序输出文。 您还可以单独指定每个文件:
- tsc --out sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts
复制代码
或者,我们可以使用文件编译(默认)为每个输入文件导出到一个JavaScript文件。 如果多个JS文件,我们可以使用 <script> 标签为加载的每个文件排,例如:
MyTestPage。 html(摘录)
- <script src="Validation.js" type="text/javascript" />
- <script src="LettersOnlyValidator.js" type="text/javascript" />
- <script src="ZipCodeValidator.js" type="text/javascript" />
- <script src="Test.js" type="text/javascript" />
复制代码
4、将外部模块导入【不常用】
TS也有外部模块的概念。 外部模块用于两种情况:node. js和require.js。 应用程序不使用node. js或require.js不需要使用外部模块,最好可以使用内部模块的组织概念 上面概述。
在编译时,每个外部模块将成为一个单独的. js文件。 类似于参考标签,编译器将遵循imports语句来编译依赖文件。
Validation.ts
- export interface StringValidator {
- isAcceptable(s: string): boolean;
- }
复制代码
LettersOnlyValidator.ts
- import validation = require('./Validation');
- var lettersRegexp = /^[A-Za-z]+$/;
- export class LettersOnlyValidator implements validation.StringValidator {
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
复制代码
ZipCodeValidator.ts
- import validation = require('./Validation');
- var numberRegexp = /^[0-9]+$/;
- export class ZipCodeValidator implements validation.StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
复制代码
Test.ts
- import validation = require('./Validation');
- import zip = require('./ZipCodeValidator');
- import letters = require('./LettersOnlyValidator');
- // Some samples to tryvar strings = ['Hello', '98052', '101'];
- // Validators to usevar validators: { [s: string]: validation.StringValidator; } = {};
- validators['ZIP code'] = new zip.ZipCodeValidator();
- validators['Letters only'] = new letters.LettersOnlyValidator();
- // Show whether each string passed each validator
- strings.forEach(s => {
- for (var name in validators) {
- console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
- }
- });
复制代码
5、代码生成外部模块
根据模块目标指定在编译,编译器将生成适当的代码为节点。 js(commonjs)或require。 js(AMD)模块加载系统。 更多信息的 define和 require生成的代码,请咨询每个模块的文档加载程序。
这个简单的例子显示了如何使用的名称在导入和导出翻译成加载模块的代码。
SimpleModule.ts
- import m = require('mod');
- export var t = m.something + 1;
复制代码
AMD / RequireJS SimpleModule.js:
- define(["require", "exports", 'mod'], function(require, exports, m) {
- exports.t = m.something + 1;
- });
复制代码
CommonJS /节点SimpleModule.js:
- var m = require('mod');
- exports.t = m.something + 1;
复制代码
6、可选模块加载和其他先进加载场景
在某些情况下,您可能希望只在一定条件下加载模块。 在TS中,我们可以使用如下所示的模式来实现这个和其他高级加载场景直接调用模块加载器在不损失类型安全。
维护类型安全,我们可以使用 typeOf 关键字。 的 typeOf 关键字,当用于输入位置,产生一个值的类型,在本例中外部模块的类型。
动态加载模块在node . js
- declare var require;
- import Zip = require('./ZipCodeValidator');
- if (needZipValidation) {
- var x: typeof Zip = require('./ZipCodeValidator');
- if (x.isAcceptable('.....')) { /* ... */ }
- }
复制代码
在require.js示例:动态加载模块
- declare var require;
- import Zip = require('./ZipCodeValidator');
- if (needZipValidation) {
- require(['./ZipCodeValidator'], (x: typeof Zip) => {
- if (x.isAcceptable('...')) { /* ... */ }
- });
- }
复制代码
7、与其他JavaScript库工作
描述的形状库不写typescript,我们需要声明类库公开的API。 因为大多数JavaScript库暴露只有少数顶级对象,模块是一个很好的方式来表示它们。 通常这些都是.d.ts文件中定义。 如果您熟悉C / c++,这些是你能想到的。让我们看看几个例子与内部和外部的例子。
环境内部模块流行的库D3定义其功能在一个名为“D3”的全局对象。 因为这个库是通过加载script 标签(而不是一个模块加载器),其声明使用内部模块来定义它的形状。TS编译器看到这个形状,我们使用一个环境内部模块声明。 例如:
D3.d.ts(简化的摘录)
- declare module D3 {
- export interface Selectors {
- select: {
- (selector: string): Selection;
- (element: EventTarget): Selection;
- };
- }
- export interface Event {
- x: number;
- y: number;
- }
- export interface Base extends Selectors {
- event: Event;
- }
- }
- declare var d3: D3.Base;
复制代码
==================================================
TypeScript教程2的更多相关文章
- TypeScript教程
汇智课堂 地址 http://www.hubwiz.com/course/55b724ab3ad79a1b05dcc26c/ TypeScript是一种由微软开发的自由和开源的编程语言.它是Java ...
- TypeScript 教程&手册
参考:https://www.w3cschool.cn/typescript/ https://www.gitbook.com/book/zhongsp/typescript-handbook/det ...
- TypeScript教程3
1.快速回顾一下这JavaScript中的命名函数和匿名函数: 纯文本查看 复制代码 1 2 3 4 5 //Named functionfunction add(x, y) { return ...
- TypeScript教程1
Boolean类型aser:和as3一样 var isDone: boolean = false; 复制代码 Number类型aser:as3经常用int和uint,以后只用number就可以啦 va ...
- 2018-05-09 5分钟入门CTS-尝鲜中文版TypeScript
知乎原链 本文为中文代码示例之5分钟入门TypeScript的CTS版本. CTS作者是@htwx(github). 它实现了关键词和标准库的所有命名汉化. 本文并未使用附带的vscode相关插件(包 ...
- HowToDoInJava 其它教程 1 · 翻译完成
原文:HowToDoInJava 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. ApacheCN 学习资源 目录 Maven 教程 如何在 ...
- 【electron+vue3+ts实战便笺exe】一、搭建框架配置
不要让自己的上限成为你的底线 前言 诈尸更新系列,为了跟上脚步,尝试了vue3,在学习vue3的时候顺便学习一手electron和ts,本教程将分别发布,源码会在最后的文章发布.因为还在开发中,目前也 ...
- 100 个常见错误「GitHub 热点速览 v.22.35」
本周的特推非常得延续上周的特点--会玩,向别人家的女朋友发送早安.这个错误是如何发生的呢?如何有效避免呢?自己用 daily_morning 免部署.定制一个早安小助手给女友吧. 除了生活中的错误,工 ...
- 转载:TypeScript 简介与《TypeScript 中文入门教程》
简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...
随机推荐
- PAT 天梯赛 L2-002 链表去重
模拟单链表的增删操作 题目链接:https://www.patest.cn/contests/gplt/L2-002 题解 最开始我脑抽用map模拟单链表进行操作,因为这样可以节约空间,并且用了cin ...
- head和tail命令-----得到头尾N行或者这去掉尾头N/N-1行
[algo@localhost tmp]$ cat test 1 2 3 4 5 head得到头部2行,删掉尾部2行 [algo@localhost tmp]$ head -n +2 test 1 ...
- Java出现“Error configuring application listener of class...”类似的错误解决
错误如下: Error configuring application listener of class com.jsoft.jblog.listener.SessionListener java. ...
- /bin/sh 与 /bin/bash 的区别
/bin/sh 与 /bin/bash 的区别,用 : 截取字符串不是POSIX 标准的. 区别 sh 一般设成 bash 的软链 (symlink) ls -l /bin/sh lrwxrwxrwx ...
- [Unity Shader]ShaderForge制作Shader
什么是ShaderForge ShaderForge的目标是推动统一的视觉质量提升到了新的高度, 给你自由的材质创建在一个视觉和直观的方式——不需要代码! ShaderForge的特性 •实时着色器预 ...
- JavaScript的Cookie操作
JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的. 而cookie是运行在客户端的,所以可以用JS来设置cookie. 假 设有这样 ...
- STM32实现HID和u盘复合设备
USB设备可以定义一个复合设备,复合设备分两种,一种是一个设备多个配置,还有一种是一个配置多个接口,在本例中采用一个配置多个接口的方式 首先修改设备描述符,标准设备描述符和报告描述符都不需要修改, ...
- UWP_小说在线阅读器:功能要求与技术要求
学了WP开发也有一年了,也没做过什么软件的.17年进发UWP,锻炼自己一下.做一个开源的小说阅读器吧. 既然开发一个软件.所以要设计一下吧. 功能要求: 可能要用到的技术,这个吗,这就是遇到问题在解决 ...
- jstree使用小结(二)
继续上一篇: 1.数据 按照官网的json数据返回格式: 有两种格式,我使用的格式如下: $('#jstree1').jstree({ 'core' : { 'data' : [ { "id ...
- Unity3d学习 基础-关于MonoBehaviour的生命周期
其实在刚接触Unity3D,会有一个疑问,关于Unity3D游戏运行的初始入口在哪?不像Cocos2dx还有个AppDelegate文件可以去理解.而且在刚开始就接触Unity3D时,看到所有脚本中编 ...