TypeScript入门

TypeScript是微软开发的JavaScript的超集,遵循ES6。由于项目需要,博主自行学习了一下TypeScript基础知识,并分享给大家,有问题请随时评论区交流~

一.TypeScript优势

  • 支持ES6规范
  • 强大的IDE支持
  • Angular2的开发语言

二.搭建TypeScript的开发环境

1.什么是compiler?为什么需要compiler?

  • 浏览器没有全面支持ES6,故需要将ES6转换成ES5

2.使用在线compiler开发

  • http://www.typescriptlang.org/play/index.html

3.使用本地compiler

  • sudo npm install -g typescript

  • 使用tsc命令的方式编译TypeScript文件

    • 创建TypeScript文件
    //创建TypeScript文件:TypeScriptTest.ts
    export class Hello{}
    • 编译TypeScript文件(会自动将编译后的js文件放至当前目录)
    tsc TypeScriptTest.ts
    • 查看编译后的js文件
    "use strict";
    exports.__esModule = true;
    var Hello = /** @class */ (function () {
      function Hello() {
      }
      return Hello;
    }());
    exports.Hello = Hello;
  • 使用WebStorm编译器可以设置直接编译TypeScript文件而不用手动编译

三.字符串新特性

1.多行字符串

  • 传统JavaScript使用多行字符串时需要用+连接,不便于阅读

    var str = "aaa" +
      "bbb" +
      "ccc";
  • TypeScript使用“包裹字符串可以直接实现多行效果

    var str = `aaa
    bbb
    ccc`;

2.字符串模板

  • 使用字符串模板,可以在字符串中直接加入对应字符串变量内容或函数调用结果,而不用再使用+拼接

  • 实例

    • TypeScript源码
    var name = "Jack wangzhe";
    var getName = function(){
      return "Jack wangzhe";
    }
    console.log(`
    
    Hello ${name} Nice to meet you, ${getName()}
    `);//使用字符串模板需要用``包裹,并在内部使用${}包裹对应变量或方法
    • 转换后的JavaScript代码
    var name = "Jack wangzhe";
    var getName = function () {
      return "Jack wangzhe";
    };
    console.log("\n
    \n Hello " + name + "\n Nice to meet you, " + getName() + "\n
    \n"
    );

3.自动拆分字符串

  • 用字符串模板调用一个方法,同时把模板里的表达式传递给方法的参数

  • 实例代码

    • TypeScript源码
    function test(template, name, age) {
      console.log(template);
      console.log(name);
      console.log(age);
    }
    var name = "Jack wangzhe";
    var getAge = function () {
      return 20;
    }
    test`Hello my name is ${name}, and I am ${getAge()}`;//自动拆分字符串传递给方法参数时不加圆括号,直接写``及其内容
    • 转换后的JavaScript
    var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
      if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
      return cooked;
    };
    function test(template, name, age) {
      console.log(template);
      console.log(name);
      console.log(age);
    }
    var name = "Jack wangzhe";
    var getAge = function () {
      return 20;
    };
    test(__makeTemplateObject(["Hello my name is ", ", and I am ", ""], ["Hello my name is ", ", and I am ", ""]), name, getAge());
    • 运行结果
    Array(3)
    Jack wangzhe
    20

    TypeScript入门_第1张图片

四.参数新特性

1.参数类型

  • 在参数名称后面使用冒号来指定参数的类型【变量、方法和方法参数都适用】

    (只会在TypeScript编辑器里进行提醒,但是编译成js不会报错,因为js是弱类型)

    TypeScript本身也有类型推断机制,在第一次为变量赋值时自动推断变量的类型,会在变量赋值类型变化时进行报错提醒。如果希望字符串被赋任何类型都不进行报错则给变量赋成any类型。

    //TypeScript代码
    var name: string = "Jack wangzhe";
    var alias: any = "xixi";
    var age: number = 18;
    var man: boolean = true;
    function test(name: string): string{
      return "";
    }
    
    //编译后的JavaScript代码
    var name = "Jack wangzhe";
    var alias = "xixi";
    var age = 18;
    var man = true;
    function test(name) {
      return "";
    }
    • any:任意类型

    • string:字符串

    • number:数字类型

    • boolean:布尔类型

    • void(声明方法的返回值):不需要任何返回值

    • 使用class或接口声明自定义类型

    //eg.
    class Person{
        name:string;
        age:number;
    }
    //使用时eg.
    var zhangsan:Person = new Person();
    zhangsan.name="zhangsan";
    zhangsan.age=18;

2.默认参数

  • 在参数声明后面用等号来指定参数的默认值(注意:带默认值的参数要声明在参数的最后面)

    //TypeScript代码
    var name:string="Jack wangzhe";
    function test(a: string, b: string, c: string = "Jack") {
      console.log(a);
      console.log(b);
      console.log(c);
    }
    test("aaa", "bbb", "ccc");
    test("aaa", "bbb");//由于c有默认值,故可传可不传
    //JavaScript代码
    var name = "Jack wangzhe";
    function test(a, b, c) {
      if (c === void 0) { c = "Jack"; }
      console.log(a);
      console.log(b);
      console.log(c);
    }
    test("aaa", "bbb", "ccc");
    test("aaa", "bbb");

3.可选参数

  • 在方法的参数声明后面用问号来标明此参数为可选参数(若没传则为undefined)

    【可选参数必须声明在必选参数的后面】

    //TypeScript代码
    function test(a: string, b?: string, c: string = "Jack") {
      console.log(a);
      console.log(b);
      console.log(c);
    }
    test("aaa");
    //JavaScript代码
    function test(a, b, c) {
      if (c === void 0) { c = "Jack"; }
      console.log(a);
      console.log(b);
      console.log(c);
    }
    test("aaa");

五.函数新特性

1.Rest and Spread操作符

  • 用来声明任意数量的方法参数(参数用...声明)
//TypeScript
function func1(...args) {
    args.forEach(function (arg) {
        console.log(arg);
    })
}
func1(1, 2, 3);
func1(7, 8, 9, 10, 11);
//JavaScript
function func1() {
    var args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        args[_i] = arguments[_i];
    }
    args.forEach(function (arg) {
        console.log(arg);
    });
}
func1(1, 2, 3);
func1(7, 8, 9, 10, 11);
  • 把任意长度的数组转换给固定数量参数的方法调用(目前TypeScript还不支持该语法,但是JavaScript支持)
//TypeScript
function func1(a,b,c) {
    console.log(a);
    console.log(b);
    console.log(c);
}
var args1 = [1, 2];
var args2 = [7, 8, 9, 10, 11];
func1(...args1);//会报错,最终输出1 2 undefined
func1(...args2);//会报错,最终输出7 8 9
//JavaScript
function func1(a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
}
var args1 = [1, 2];
var args2 = [7, 8, 9, 10, 11];
func1.apply(void 0, args1);
func1.apply(void 0, args2);

2.generator函数

  • 控制函数的执行过程,手工暂停和恢复代码执行(TypeScript还不支持该语法,本例使用Babel进行编译)
//TypeScript代码
function* doSomeThing(){
    console.log("start");
    yield;
    console.log("end");
}
var test = doSomeThing();
test.next();//输出start,停在yield
test.next();//输出end

//JavaScript代码
"use strict";
var _marked = /*#__PURE__*/regeneratorRuntime.mark(doSomeThing);
function doSomeThing() {
  return regeneratorRuntime.wrap(function doSomeThing$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          console.log("start");
          _context.next = 3;
          return;

        case 3:
          console.log("end");

        case 4:
        case "end":
          return _context.stop();
      }
    }
  }, _marked, this);
}
var test = doSomeThing();
test.next();
test.next();

3.destructing析构表达式

  • 通过表达式将对象或数组拆解成任意数量的变量针对对象的析构表达式用{},针对数组的析构表达式用[]
    • 解析的对象的属性要和析构出的变量名相同,或使用对象属性名:新变量名对变量进行赋值
    • 若存在嵌套问题,则可以嵌套多个析构表达式进行匹配
    • 好处:当需要从对象的属性或者是数组的元素中用他们的值去初始化本地本地变量时,使用析构表达式可以帮助我们写更少的代码
//利用析构表达式从对象中拆分属性
function getStock() {
    return {
        code: "CodeTest",
        price: {
            price1: 200,
            price2:400
        },
        aaa: "aaa",
        bbb: "bbb"
    }
}
var { code: codex, price: { price2 } } = getStock();

console.log(codex);//CodeTest
console.log(price2);//400
//使用析构表达式从数组中拆分元素
var array1 = [1, 2, 3, 4];
var [num1, , num2] = array1;
console.log(num1);//1
console.log(num2);//3
var [num1, num2, ...others] = array1;
console.log(others);//[3,4]
function doSomeThing([num1, num2, ...others]) {
    console.log(num1);//1
    console.log(num2);//2
    console.log(others);//[3,4,5]
}
doSomeThing([1, 2, 3, 4, 5]);

六.表达式与循环

1.箭头表达式

  • 用来声明匿名函数,消除传统匿名函数的this指针问题

    • (参数)=>{函数体}若参数为一个则()可以省略直接写参数,若只有一个表达式则{}可以省略直接写内容
  • 实例代码

    function getStock1(name: string) {
      this.name = name;
      setInterval(function () {
          console.log(`name is ${this.name}`);
      }, 1000);
    }
    getStock1("Jack");//循环输出this is   [目前最新测试已经修复此问题,会正常输出this is Jack]
    
    function getStock2(name: string){
      this.name = name;
      setInterval(()=>{
          console.log(`name is ${this.name}`);
      }, 1000);
    }
    getStock2("Tom");//循环输出this is Tom

2.forEach(),for in和for of

  • forEach()只循环数组元素不循环到数组属性

  • for in循环数组中元素下标和属性名

  • for of循环数组中数组元素(不循环属性值),且可以使用break关键字停止循环

  • 实例代码

    var array = [1, 2, 3, 4];
    array.name = "Jack";//在TypeScript中编译会报错,因为TypeScript不支持给数组添加属性的语法
    array.forEach(val => console.log(val));//1 2 3 4
    for (var key in array) {
      console.log(key);//0 1 2 3 name
    }
    for (var val of array) {
      console.log(val);//1 2 3 4
    }
    for (var val of array) {
      if (val == 3) {
          break;//1 2
      }
      console.log(val);
    }

七.面向对象特性

1.类(Class)

  • 类是TypeScript的核心,使用TypeScript开发时,大部分代码都是写在类里面的
  • 类的定义
class Person{
    name;
    eat(){
        console.log("I am eating");
    }
}
var p1 = new Person();//类的实例化
p1.name = "batman";
p1.eat();
  • 访问控制符

    • public在类的内部和外部都能被访问到(默认)
    • private在类的内部才能访问到
    • protected在类的内部及类的子类能访问到
  • 类的构造方法

    • 在类的实例化的时候被调用,且只被调用一次

    • 方法名称constructor(参数)

    • 当构造方法参数为public属性修饰时,会自动将该参数作为类的属性并赋值(如果没有加public则不将对应的参数声明为属性)

    //eg.
    class Person{
        constructor(public name:string){
    
        }
        eat(){
            console.log(this.name);
        }
    }
    var p1 = new Person("batman");//执行的操作为将batman赋值给name,name作为Person的属性值存在
    p1.eat();//batman
  • 类的继承

    • extends用来声明一种继承的关系。
    • 当一个类继承了另外一个类时,则具有了另一个类所有的属性和方法。
    • super
      • 子类的构造函数必须要调用父类的构造函数
      • 用来调用父类的构造函数super(参数)
      • 直接调用父类的方法或属性super.父类方法();super.父类属性;

2.泛型(generic)

  • 参数化的类型,一般用来限制集合的内容,只能放特定类型的元素,不能放其他类型的元素
//eg.
var workers:Array = [];
workers[0] = new Person("Jack");//成功,将Person对象放置workers中
workers[1] = new Employee("Tom","2");//成功,将Employee对象放置workers中(因为Employee是Person类的子类)
workers[2] = 2;//编译报错,不能放置非Person类型的元素

3.接口(Interface)

  • 用来建立某种代码约定,使得其它开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定
    • 使用方法1:使用接口作为属性。定义接口使用interface声明。当接口作为方法参数的类型声明时,调用方法时,typescript会去检查传入的参数是否满足声明时接口中的所有属性。
    • 使用方法2:定义类实现接口。使用implements实现接口,当一个类实现了某个接口,则必须实现该接口的所有方法。
//声明接口
interface IPerson{
    name:string;
    age:number;
}
//声明类
class Person{
    constructor(public config:IPerson){}
}
//调用
var p1 = new Person({
    name:"zhangsan",
    age:18
});//多传一个或少传一个属性都会报错,因为没有满足接口所声明的属性的要求

//声明动物接口
interface EatSomeThing{
    eat();//接口中的方法没有方法体
}
//实现类
class Cat implements EatSomeThing{
    eat(){//需要实现接口中的所有方法
        console.log("I like eat Meat")
    }
}

4.模块(Module)

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

    • export导出
    • import导入
    //a.ts
    export var prop1;
    var prop2;//没有对外暴露
    export function func1(){
    
    }
    function func2(){
    
    }//没有对外暴露
    export class Clazz1{
    
    }
    class Clazz2{
    
    }//没有对外暴露
    //b.ts
    import{prop1,func1,Clazz1} from './a';
    console.log(prop1);
    func1();
    new Clazz1();

5.注解(annotation)

  • 注解为程序的元素(类、方法、变量)加上更直接更明了的说明,这些说明信息与程序的业务逻辑无关,而是供指定的工具或框架使用的。

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

  • 类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包(如:JQuery)

    【这个文件其实就是一个TypeScript的模块,它把要使用的JavaScript要使用的工具包中的工具以TypeScript模块的形式暴露出来,从而使用】

    • 先引入jquery的类型定义文件index.d.ts【下载地址:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jquery/index.d.ts】

    • 使用时直接使用对应jquery的方法即可

    //eg.
    export function func1(){
        $("xxx").hide();   
    }
    • 常用JavaScript框架的类型定义文件地址

    【https://github.com/DefinitelyTyped/DefinitelyTyped】

    • 安装类型定义文件的工具地址及安装方法,使用工具可以直接下载对应框架的类型定义文件

    【https://github.com/typings/typings】

你可能感兴趣的:(前端技术相关)