前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从 JavaScript 到 TypeScript

从 JavaScript 到 TypeScript

作者头像
牧云云
发布于 2018-04-28 08:55:20
发布于 2018-04-28 08:55:20
1.5K00
代码可运行
举报
文章被收录于专栏:云瓣云瓣
运行总次数:0
代码可运行

TypeScript 并不是一个完全新的语言, 它是 JavaScript 的超集,为 JavaScript 的生态增加了类型机制,并最终将代码编译为纯粹的 JavaScript 代码。

TypeScript 简介

TypeScript 由 Microsoft(算上 Angular 2 的话加上 Google)开发和维护的一种开源编程语言。 它支持 JavaScript 的所有语法和语义,同时通过作为 ECMAScript 的超集来提供一些额外的功能,如类型检测和更丰富的语法。下图显示了 TypeScript 与 ES5,ES2015,ES2016 之间的关系。

使用 TypeScript 的原因

JavaScript 是一门弱类型语言,变量的数据类型具有动态性,只有执行时才能确定变量的类型,这种后知后觉的认错方法会让开发者成为调试大师,但无益于编程能力的提升,还会降低开发效率。TypeScript 的类型机制可以有效杜绝由变量类型引起的误用问题,而且开发者可以控制对类型的监控程度,是严格限制变量类型还是宽松限制变量类型,都取决于开发者的开发需求。添加类型机制之后,副作用主要有两个:增大了开发人员的学习曲线,增加了设定类型的开发时间。总体而言,这些付出相对于代码的健壮性和可维护性,都是值得的。

此外,类型注释是 TypeScript 的内置功能之一,允许文本编辑器和 IDE 可以对我们的代码执行更好的静态分析。 这意味着我们可以通过自动编译工具的帮助,在编写代码时减少错误,从而提高我们的生产力。

对 TypeScript 的简介到此,接下来对其特有的知识点进行简单概括总结,(网上很多教程实际上把 ES6, ES7 的知识点也算进 ts 的知识点了,当然这没错~)

数据类型
String 类型

一个保存字符串的文本,类型声明为 string。可以发现类型声明可大写也可小写,后文同理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let name: string = 'muyy'
let name2: String = 'muyy'
Boolen 类型

boolean是 true 或 false 的值,所以 let isBool3: boolean = new Boolean(1) 就会编译报错,因为 new Boolean(1) 生成的是一个 Bool 对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let isBool1: boolean = false
Number 类型
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let number: number = 10;
Array 类型

数组是 Array 类型。然而,因为数组是一个集合,我们还需要指定在数组中的元素的类型。我们通过 Array<type> or type[] 语法为数组内的元素指定类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let arr:number[] = [1, 2, 3, 4, 5];
let arr2:Array<number> = [1, 2, 3, 4, 5];

let arr3:string[] = ["1","2"];
let arr4:Array<string> = ["1","2"];
Enums 类型

列出所有可用值,一个枚举的默认初始值是0。你可以调整一开始的范围:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum Role {Employee = 3, Manager, Admin}
let role: Role = Role.Employee
console.log(role) // 3
Any 类型

any 是默认的类型,其类型的变量允许任何类型的值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let notSure:any = 10;
let notSure2:any[] = [1,"2",false];
Void 类型

JavaScript 没有空值 Void 的概念,在 TypeScirpt 中,可以用 void 表示没有任何返回值的函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function alertName(): void {
  console.log('My name is muyy')
}
函数
为函数定义类型

我们可以给每个参数添加类型之后再为函数本身添加返回值类型。 TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。下面函数 add, add2, add3 的效果是一样的,其中是 add3 函数是函数完整类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function add(x: string, y: string): string{
    return "Hello TypeScript";
}

let add2 = function(x: string, y: string): string{
    return "Hello TypeScript";
}

let add3: (x: string, y: string) => string = function(x: string, y: string): string{
    return "Hello TypeScript";
}
可选参数和默认参数

JavaScript 里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是 undefined 。 在 TypeScript 里我们可以在参数名旁使用?实现可选参数的功能。 比如,我们想让 lastname 是可选的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function buildName(firstName: string, lastname?: string){
    console.log(lastname ? firstName + "" + lastname : firstName)
}

let res1 = buildName("鸣","人"); // 鸣人
let res2 = buildName("鸣"); // 鸣
let res3 = buildName("鸣", "人", "君"); // Supplied parameters do not match any signature of call target.

如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined 值来获得默认值。 例如,我们重写上例子,让 firstName 是带默认值的参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function buildName2(firstName = "鸣", lastName?: string){
    console.log(firstName + "" + lastName)
}

let res4 = buildName2("人"); // undefined人
let res5 = buildName2(undefined, "人"); // 鸣人

传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 使用TypeScript,我们允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person{
    name:string; // 这个是对后文this.name类型的定义
    age:number;
    constructor(name:string,age:number){
        this.name = name;
        this.age = age;
    }
    print(){
        return this.name + this.age;
    }
}

let person:Person = new Person('muyy',23)
console.log(person.print()) // muyy23

我们在引用任何一个类成员的时候都用了 this。 它表示我们访问的是类的成员。其实这本质上还是 ES6 的知识,只是在 ES6 的基础上多上了对 this 字段和引用参数的类型声明。

继承
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person{
    public name:string;  // public、private、static 是 typescript 中的类访问修饰符
    age:number;
    constructor(name:string,age:number){
        this.name = name;
        this.age = age;
    }
    tell(){
        console.log(this.name + this.age);
    }
}

class Student extends Person{
    gender:string;
    constructor(gender:string){
        super("muyy",23);
        this.gender = gender;
    }
    tell(){
        console.log(this.name + this.age + this.gender);
    }
}

var student = new Student("male");
student.tell();  // muyy23male

这个例子展示了 TypeScript 中继承的一些特征,可以看到其实也是 ES6 的知识上加上类型声明。不过这里多了一个知识点 —— 公共,私有,以及受保护的修饰符。TypeScript 里,成员默认为 public ;当成员被标记成 private 时,它就不能在声明它的类的外部访问;protected 修饰符与private 修饰符的行为很相似,但有一点不同,protected 成员在派生类中仍然可以访问。

存储器

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

对于存取器有下面几点需要注意的: 首先,存取器要求你将编译器设置为输出 ECMAScript 5 或更高。 不支持降级到 ECMAScript 3。 其次,只带有 get 不带有 set 的存取器自动被推断为 readonly。 这在从代码生成 .d.ts 文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Hello{
    private _name: string;
    private _age: number;
    get name(): string {
        return this._name;
    }
    set name(value: string) {
        this._name = value;
    }
    get age(): number{
        return this._age;
    }
    set age(age: number) {
        if(age>0 && age<100){
            console.log("年龄在0-100之间"); // 年龄在0-100之间
            return;
        }
        this._age = age;
    }
}

let hello = new Hello();
hello.name = "muyy";
hello.age = 23
console.log(hello.name); // muyy
接口
接口

TypeScript的核心原则之一是对值所具有的结构进行类型检查。在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface LabelValue{
    label: string;
}

function printLabel(labelObj: LabelValue){
    console.log(labelObj.label);
}

let myObj = {
    "label":"hello Interface"
};
printLabel(myObj);

LabelledValue 接口就好比一个名字,它代表了有一个 label 属性且类型为 string 的对象。只要传入的对象满足上述必要条件,那么它就是被允许的。

另外,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。

可选属性

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 ? 符号。可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface Person{
    name?:string;
    age?:number;
}

function printInfo(info:Person){
    console.log(info);
}

let info = {
    "name":"muyy",
    "age":23
};

printInfo(info); // {"name": "muyy", "age": 23}

let info2 = {
    "name":"muyy"
};

printInfo(info2); // {"name": "muyy"}
函数类型

接口能够描述 JavaScript 中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。定义的函数类型接口就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。定义后完成后,我们可以像使用其它接口一样使用这个函数类型的接口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface SearchFunc{
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string,subString: string){
    return source.search(subString) !== -1;
};

console.log(mySearch("鸣人","鸣")); // true
console.log(mySearch("鸣人","缨")); // false
可索引类型

与使用接口描述函数类型差不多,我们也可以描述那些能够“通过索引得到”的类型,比如 a[10]ageMap["daniel"]。 可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。 让我们看如下例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface StringArray{
    [index: number]: string;
}

let MyArray: StringArray;
MyArray = ["是","云","随","风"];
console.log(MyArray[2]); // 随
类类型

与 C# 或 Java 里接口的基本作用一样,TypeScript 也能够用它来明确的强制一个类去符合某种契约。

我们可以在接口中描述一个方法,在类里实现它,如同下面的 setTime 方法一样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface ClockInterface{
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface{
    currentTime: Date;
    setTime(d: Date){
        this.currentTime = d;
    }
    constructor(h: number, m: number) {}
}
继承接口

和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface Shape{
    color: string;
}

interface PenStroke{
    penWidth: number;
}

interface Square extends Shape,PenStroke{
    sideLength: number;
}

let s = <Square>{};
s.color = "blue";
s.penWidth = 100;
s.sideLength = 10;
模块

TypeScript 与 ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export interface StringValidator{
    isAcceptable(s:string): boolean;
}

var strReg = /^[A-Za-z]+$/;
var numReg = /^[0-9]+$/;

export class letterValidator implements StringValidator{
    isAcceptable(s:string): boolean{
        return strReg.test(s);
    }
}

export class zipCode implements StringValidator{
    isAcceptable(s: string): boolean{
        return s.length == 5 && numReg.test(s);
    }
}
泛型

软件工程中,我们不仅要创建一致的定义良好的 API ,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。 在像 C# 和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

初探泛型

如下代码,我们给 Hello 函数添加了类型变量 T ,T 帮助我们捕获用户传入的类型(比如:string)。我们把这个版本的 Hello 函数叫做泛型,因为它可以适用于多个类型。 代码中 outputoutput2 是效果是相同的,第二种方法更加普遍,利用了类型推论 —— 即编译器会根据传入的参数自动地帮助我们确定T的类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Hello<T>(arg:T):T{
    return arg;
}

let outPut = Hello<string>('Hello Generic');
let output2 = Hello('Hello Generic')

console.log(outPut);
console.log(outPut2);
参考资料
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-07-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Odyssey
今天上午看到odyssey推特上有了新动静,随后1.0.0就出来了,但是签名安装之后会闪退,我着急忙慌的看了一下包,初步认定是pilst问题,因为在上班,没仔细看,结果后来一看我打开的是vscode编辑器的json配置。。。。
zby1101
2020/09/01
5850
Odyssey
全系(iOS7-iOS14)清除越狱教程
前几天一个群友11.0.3想清除越狱了,这系统一看就是买来手机没升级过系统,为了保留系统,清除掉越狱,众所周知,10.3+有了系统快照(system snap)那就直接用snapback呗,后来询问得知,越狱环境也有问题,cydia装不上插件,后来小编请教了一位大佬,回忆起11.0-11.3可以利用脚本清理越狱,今天就整理一下iOS7-iOS14系清理越狱的教程吧(全凭小编自己的知识存储,可能某些系统还有别的方法,我尽可能的多写几种方法)
zby1101
2020/10/23
14.9K0
全系(iOS7-iOS14)清除越狱教程
【iOS】浅析近期越狱工具+“平刷”工具
越狱工具:unc0ver,chimera,checkra1n(chimera1n)
zby1101
2020/08/05
6.2K0
【iOS】浅析近期越狱工具+“平刷”工具
ios逆向之使用AltDeploy安装未签名ipa
在对iOS app进行安全分析时,为了动态调试iOS app或者hook iOS app,需要先将app安装到手机中。有的iOS app可以通过App Store或者其他手机助手app直接下载安装,而其他未签名app则需要通过电脑手动安装到手机中。之前我们一直使用cydia impactor进行安装,现在由于apple服务器端内调整,导致通过cydia impactor无法安装ipa。因此我们则需要使用AltDeploy代替cydia impactor来安装ipa。接下来将介绍安装流程。
用户4682003
2022/05/19
2K0
ios逆向之使用AltDeploy安装未签名ipa
unc0ver5.0.0完美解决卡1、卡25的问题_钟意博客
最近unCover5.0.0版本的发布让大家热血沸腾,但是可以发现会有卡1、卡25问题,那么这个文章就来解决这个问题.
RONG荣
2021/10/11
5.3K0
unc0ver5.0.0完美解决卡1、卡25的问题_钟意博客
iOS逆向之使用unc0ver越狱 iOS13.5
因为工作需要,笔者最近在研究越狱,网上看了很多文章,这篇文章记录了给iOS 13设备越狱的方式和过程,希望对你有帮助。
VV木公子
2020/09/11
13K0
iOS逆向之使用unc0ver越狱 iOS13.5
【iOS】越狱后的“救命稻草”
pwn最近更新了好几次unc0ver,相信各位朋友已经在各大公众号,论坛看到了,这里就不说它了
zby1101
2020/08/05
9430
【iOS】越狱后的“救命稻草”
iOS越狱是什么?大佬来解释来咯(一)
那么root是什么呢,无论安卓和iOS都有两个用户,一个是root,另一个是mobile,前者相当于windowns的system,也就是管理员administrator,后者相当于一个非管理员用户,没有拥有系统管理权限,通过一些特殊手段,例如第三方root工具,这里我就不详细说了,因为我接触安卓不多,不再赘述。
zby1101
2020/08/05
1.1K0
【iOS】关于iOS13越狱的一些事情
由于前几天偶然发现自己家宽带竟然是公网ip,这段时间一直在试着折腾一下ftp服务器,后面可能会写一篇搭建私有云(是ftp还是硬盘,还是类似网盘的的教程,随缘吧)
zby1101
2020/08/05
7660
【iOS】关于iOS13越狱的一些事情
【教程】几种屏蔽iOS端ota升级的几种办法
第一种:(通用)就是利用升级tvos的测试版的描述文件装到手机上,这种方法就是今天失效的这个
zby1101
2020/08/05
3.2K0
【教程】几种屏蔽iOS端ota升级的几种办法
【ios客户端渗透测试】测试机越狱和屏蔽越狱检测
ios 不能安装没有进行安全签名的应用,所以尝试使用爱思助手直接安装 unc0ver 8.0.2 失败,提示“设备未安装AppSync越狱补丁”。
全栈程序员站长
2022/08/22
8.1K0
【ios客户端渗透测试】测试机越狱和屏蔽越狱检测
ios逆向-frida&环境&破解appSign算法
比WIFI响应速度快,网络环境无限制 usbmuxd是网上开源社区,貌似是国外牛人倾力打造的一个专门针对该功能开源库 通过brew来安装brew install usbmuxdusbmuxd 自带工具iproxy,iproxy 可以快捷的操作连接iPhone等操作。由于Mac上只支持4位的端口号,所以需要把iPhone的默认端口22映射到Mac上,相当于建立一个Mac和iPhone之间的通道。iproxy 2222 22以上命令就是把当前连接设备的22端口(SSH端口)映射到电脑的1215端口,那么想和设备22端口通信,直接和本地的1215端口通信就可以了。终端提示 waiting for connection ,表示这两个端口之间已经可以通信了,保留当前终端(如果关闭就停止端口之间的通信了),新建另一个终端输入,默认密码:alpinessh -p 2222 root@127.0.0.1
吾爱小白
2020/12/02
4.3K0
ios逆向-frida&环境&破解appSign算法
盘古正式发布IOS 7.1.1 完美越狱
在经过一段时间的酝酿之后,中国越狱团队正式发布了 IOS 7.1.1 完美越狱工具,兼容所有运行 IOS 7.1-7.1.1的设备。
reizhi
2022/09/26
6580
盘古正式发布IOS 7.1.1 完美越狱
苹果ios爱思助手企业证书自签的详细图文教程
3.添加好Apple ID后,添加 IPA,根据自己喜好选择越狱工具,这里以Unc0ver为例。
季春二九
2023/04/27
4.6K0
苹果ios爱思助手企业证书自签的详细图文教程
iOS越狱是什么?大佬来解释来咯(二)
众所周知,越狱可以获取最高权限,而在iOS上访问系统根目录是需要最高系统权限的(虽然也有不需要越狱获取文件系统的实例)
zby1101
2020/08/05
1.1K0
iOS越狱是什么?大佬来解释来咯(二)
ios5.1.1越狱实践
今天一口气越狱了三台ipad,虽然是第一次越狱,但是借助于现在网络的发达,基本算是很顺利就完成了越狱。
全栈程序员站长
2022/08/26
8760
IOS 越狱插件介绍与一点经验
总体来说,如果你的系统是13.5的话(尚未升级到13.5.1),实际上整个流程比Android的Root还要简单。因为Iphone是我的主力机,为了避免不必要的麻烦,一直没有做越狱操作。
xuing
2020/06/17
3.1K0
IOS 越狱插件介绍与一点经验
使用Reveal查看APP视图层级
1、爱思助手点击一键越狱后,设备上会出现两个APP: unc0ver Cydia。
用户6094182
2022/05/13
1.3K0
使用Reveal查看APP视图层级
iOS10 iPhone5 10.3.3每次越狱后要做的事「建议收藏」
1.越狱设备安装“AFC2”补丁。https://www.i4.cn/news_detail_1623.html
全栈程序员站长
2022/07/01
1.4K0
iOS逆向(10)-越狱!越狱!远程连接登录手机
之前的九篇文章讲述的是在不越狱的情况下,详细的讲解了对APP重签名的原理,如何动态库注入,以及之后的各种调试技巧。这些功能其实已经很强大了,能够帮助咱们在绝大多数情况下去分析并且更改对方的APP了。这对付一些在开发过程中没有安全意识的APP其实已经足以。但是但凡对方有对APP进行防护,那么重签名就显得有些弱鸡了。
iOSSir
2019/06/14
2.2K0
iOS逆向(10)-越狱!越狱!远程连接登录手机
相关推荐
Odyssey
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档