美文网首页跨平台
Typescript了解

Typescript了解

作者: 平安喜乐698 | 来源:发表于2020-02-27 19:04 被阅读0次
    目录
    
    
    
    1. 微软开发的编程语言(开源) , 用于开发大型应用
    
    2. JavaScript的超集,对JavaScript语法进行了扩展。
        JavaScript代码可以和TypeScript代码一起工作,TypeScript只会对其中的TypeScript代码进行编译
    
    3. 支持ECMAScript 6标准
    

    安装

    1. 方式一
    npm install -g typescript
    
    查看是否安装成功(输出版本号则代表安装成功)
      tsc -v    
    
    编译ts文件
      tsc hello.ts
    同时编译多个文件(会生成多个js文件)
      tsc hello.ts hello2.ts
    
    参数 说明
    --out 编译多个文件并合并到一个输出的文件(默认是每个ts文件编译为单独的js文件) 例:tsc --out test.js TestPerson.ts Test.ts
    --help 显示帮助信息
    --module 载入扩展模块
    --target 设置 ECMA 版本
    --declaration 额外生成一个 .d.ts 扩展名的文件
    --removeComments 删除文件的注释
    --sourcemap 生成一个 sourcemap (.map) 文件。sourcemap 是一个存储源代码与编译代码对应位置映射的信息文件。
    --module noImplicitAny 在表达式和声明上有隐含的 any 类型时报错
    --watch 在监视模式下运行编译器。会监视输出文件,在它们改变时重新编译。
    1. 方式二
      Visual Studio的TypeScript插件
    
    1. hello world

    新建hello.ts文件

    function func(param) {
        return param;
    }
    
    let hello = "Hello World!";
    
    document.body.innerHTML = func(hello);
    

    编译hello.ts文件 (同目录下生成hello.js文件)

    tsc hello.ts
    

    创建index.html文件,内容如下(在浏览器中打开可查看效果)

    <!-- index.html -->
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>hello world</title>
      </head>
      <body>
      <script type="text/javascript" src="hello.js"></script></body>
    </html>
    

    1. 语法

    1. 基础语法
    1. 忽略 制表符、换行符、多余的空格 (这些空格只用于使代码易于阅读和理解,当ts文件编译为js文件的时候就会被清除,同时会在合适位置添加空格以使代码规范)
      举例
          document.body.innerHTML               =greeter(teacher);
      编译后:
      document.body.innerHTML = greeter(teacher);
    
    2. 大小写敏感
    
    3. 一行只有一个语句时,语句后面的分号是可选的。一行多个语句时必须加分号。
    
    4. 注释
      单行注释 // 
      多行注释 /* */
    
    5. 运算符(同Javascript,见Javascipt基础回忆篇) 
    
    1. 变量

    变量名

      1. 不能以数字开头
      2. 除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格
      3. 可以包含数字和字母
    
    注意:
      1. 变量名不要使用 name,否则会与 DOM 中的全局 window 对象下的 name 属性出现了重名。
      2. Typescript属于强类型语言
        var num:number = "hello"     // 这个代码会编译错误
    

    变量声明和赋值

    变量使用前必须先声明,使用 var 来声明变量
    
    1. 
    var [变量名] : [类型] = 值;
    例:
      var xname:string = "cx";
    
    2. 
    var [变量名] : [类型];
    var [变量名] = 值;
    例:
      var xname:string;
      xname =  "cx";
    

    类型注释

    当给变量添加类型注释后,给变量赋值其他类型的值,编译时会报错
    var tmp:string  = "hello";
    tmp = 5;  // 报错
    
    
    
    例:
    给param添加类型注释,向greeter函数传入非string类型数据,使用tsc hello.ts编译时会报错
    function greeter(param: string) {
        return "just, " + param;
    }
    let hello = ["hello","world"];
    document.body.innerHTML = greeter(hello);
    
    报如下错误:
    hello.ts:7:35 - error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'.
    

    类型断言

    用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。
    类型断言工作在编译时。
    
    方式一
    <类型>值
    
    方式二
    值 as 类型
    
    
    例1
    ========================== ts
    var str = '1' 
    var str2:number = <number> <any> str   //str、str2 是 string 类型
    console.log(typeof str);
    console.log(typeof str2);
    ========================== js
    var str = '1';
    var str2 = str; //str、str2 是 string 类型
    console.log(typeof str);
    console.log(typeof str2);
    ========================== 输出
    string
    string
    

    类型推断

    当类型没有给出时,TypeScript 编译器利用类型推断来推断类型。
    如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。
    
    var num = 2;    // 类型推断为 number
    console.log("num 变量的值为 "+num); 
    num = "12";    // 编译错误
    console.log(num);
    

    变量作用域

    1. 全局作用域 
        全局变量定义在程序结构的外部,可以在代码的任何位置使用。
    
    2. 类作用域 
        该变量也可以称为 字段。
        类变量声明在一个类里头,但在类的方法外面。 该变量可以通过类的对象来访问。类变量也可以是静态的,静态的变量可以通过类名直接访问。
    
    3. 局部作用域 
        局部变量,局部变量只能在声明它的代码块(如:方法)中使用
    
    
    例1
    ========================== ts
    var global_num = 12          // 全局变量
    class Numbers { 
       num_val = 13;             // 实例变量
       static sval = 10;         // 静态变量
       
       storeNum():void { 
          var local_num = 14;    // 局部变量
       } 
    } 
    console.log("全局变量为: "+global_num)  
    console.log(Numbers.sval)   // 静态变量
    var obj = new Numbers(); 
    console.log("实例变量: "+obj.num_val)
    ========================== js
    var global_num = 12; // 全局变量
    var Numbers = /** @class */ (function () {
        function Numbers() {
            this.num_val = 13; // 类变量
        }
        Numbers.prototype.storeNum = function () {
            var local_num = 14; // 局部变量
        };
        Numbers.sval = 10; // 静态变量
        return Numbers;
    }());
    console.log("全局变量为: " + global_num);
    console.log(Numbers.sval); // 静态变量
    var obj = new Numbers();
    console.log("类变量: " + obj.num_val);
    ========================== 输出
    全局变量为: 12
    10
    类变量: 13
    

    联合类型 |

    通过 管道| 将变量设置为多种类型
    
    var x=Type1|Type2|Type3;
    
    
    例1
    ========================== ts
    var num:string|number; 
    num = 100; 
    console.log("数字为 "+ num);
    num = "100";
    console.log("字符串为 " + num);
    ========================== js
    var num;
    num = 100;
    console.log("数字为 " + num);
    num = "100";
    console.log("字符串为 " + num);
    ========================== 输出
    数字为 100
    字符串为 100
    
    
    例2
    ========================== ts
    function func(name:string|string[]) { 
        if(typeof name == "string") { 
            console.log(name); 
        } else { 
            var i; 
            for(i = 0;i<name.length;i++) { 
                console.log(name[i]);
            } 
        } 
    }
    func("cx");
    func(["LiuDeHua","ZhouRunFa","ZhouXingChi","cx"]);
    ========================== js
    function func(name) {
        if (typeof name == "string") {
            console.log(name);
        }
        else {
            var i;
            for (i = 0; i < name.length; i++) {
                console.log(name[i]);
            }
        }
    }
    func("cx");
    func(["LiuDeHua", "ZhouRunFa", "ZhouXingChi", "cx"]);
    ========================== 输出
    cx
    LiuDeHua
    ZhouRunFa
    ZhouXingChi
    cx
    
    
    例3
    ========================== ts
    var array:number[]|string[]; 
    array = [100,500,1000]; 
    var i:number; 
    for(i = 0;i<array.length;i++) { 
       console.log(array[i]); 
    }  
    array = ["ZHouXingChi","LiuDeHua","cx"];
    for(i = 0;i<array.length;i++) { 
       console.log(array[i]); 
    }
    ========================== js
    var array;
    array = [100, 500, 1000];
    var i;
    for (i = 0; i < array.length; i++) {
        console.log(array[i]);
    }
    array = ["ZHouXingChi", "LiuDeHua", "cx"];
    for (i = 0; i < array.length; i++) {
        console.log(array[i]);
    }
    ========================== 输出
    100
    500
    1000
    ZHouXingChi
    LiuDeHua
    cx
    
    1. 函数
    实现某个功能的语句块,函数声明包含函数名、参数、返回类型
    
    function function_name(){
    }
    
    function function_name():return_type { 
        return value; 
    }
    
    // 可选参数必须位于最后
    function func_name( param1 [:datatype],param2[:type] = default_value, param3? [:datatype]) {   
    }
    
    // 剩余参数(参数个数未知)
    function buildName(firstName: string, ...restOfName: string[]) {
        return firstName + " " + restOfName.join(" ");
    }
    
    // 匿名函数(没有函数名)
    var res = function( [arguments] ) { ... }  
    
    // 函数重载(方法名字相同,参数不同),参数不同:类型不同、个数不同、顺序不同
    function disp(string):void; 
    function disp(number):void;
    
    // 构造函数
    var res = new Function( [arguments] ) { ... })
    
    // 递归函数(函数内调用函数本身,必须有临界条件,否则无限循环)
    。。。
    
    // Lambda函数(箭头函数)
    ( [param1, parma2,…param n] )=>statement
    

    例1

    function test() {   // 函数定义
        console.log("调用函数") 
    } 
    test()              // 调用函数
    

    例2

    // 函数定义
    function greet():string { // 返回一个字符串
        return "Hello World" 
    } 
     
    function caller() { 
        var msg = greet() // 调用 greet() 函数 
        console.log(msg) 
    } 
     
    // 调用函数
    caller()
    

    例3

    ========================== ts
    function add(x: number, y: number): number {
        return x + y;
    }
    console.log(add(1,2));  
    ========================== js
    function add(x, y) {
        return x + y;
    }
    console.log(add(1, 2));
    ========================== 输出
    3
    

    例4 (可选参数)

    ========================== ts
    function buildName(firstName: string, lastName?: string) {
        if (lastName)
            return firstName + " " + lastName;
        else
            return firstName;
    }
    let result1 = buildName("Bob");  // 正确
    let result2 = buildName("Bob", "Adams", "Sr.");  // 错误,参数太多了
    let result3 = buildName("Bob", "Adams");  // 正确
    ========================== js
    function buildName(firstName, lastName) {
        if (lastName)
            return firstName + " " + lastName;
        else
            return firstName;
    }
    var result1 = buildName("Bob"); // 正确
    // let result2 = buildName("Bob", "Adams", "Sr.");  // 错误,参数太多了
    var result3 = buildName("Bob", "Adams"); // 正确
    

    例5 (默认参数)

    ========================== ts
    function calculate_discount(price:number,rate:number = 0.50) { 
        var discount = price * rate; 
        console.log("计算结果: ",discount); 
    } 
    calculate_discount(1000) 
    calculate_discount(1000,0.30)
    ========================== js
    function calculate_discount(price, rate) {
        if (rate === void 0) { rate = 0.50; }
        var discount = price * rate;
        console.log("计算结果: ", discount);
    }
    calculate_discount(1000);
    calculate_discount(1000, 0.30);
    ========================== 输出
    计算结果:  500
    计算结果:  300
    

    例6 (剩余参数)

    ========================== ts
    function buildName(firstName: string, ...restOfName: string[]) {
        return firstName + "///////" + restOfName.join(" ");
    }
    let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");  
    console.log(employeeName);
    ========================== js
    function buildName(firstName) {
        var restOfName = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            restOfName[_i - 1] = arguments[_i];
        }
        return firstName + "///////" + restOfName.join(" ");
    }
    var employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
    console.log(employeeName);
    ========================== 输出
    Joseph///////Samuel Lucas MacKinzie
    

    例7 (匿名函数)

    ========================== ts
    var msg = function() { 
        return "hello world";  
    } 
    console.log(msg());
    ========================== js
    var msg = function () {
        return "hello world";
    };
    console.log(msg());
    ========================== 输出
    hello world
    

    例8 (匿名函数2)

    ========================== ts
    (function () { 
        var x = "Hello!!";   
        console.log(x)     
     })()
    ========================== js
    (function () {
        var x = "Hello!!";
        console.log(x);
    })();
    ========================== 输出
    Hello!!
    

    例9 (函数重载)

    ========================== ts
    function func(s1:string):void;
    function func(s1:number):void;
    
    function func(s1:any):void{
        console.log(s1);
    }
    func(1);
    ========================== js
    function func(s1) {
        console.log(s1);
    }
    func(1);
    ========================== 输出
    1
    

    例10 (函数重载2)

    ========================== ts
    function disp(s1:string):void; 
    function disp(n1:number,s1:string):void; 
     
    function disp(x:any,y?:any):void { 
        console.log(x); 
        console.log(y); 
    } 
    disp("abc") 
    disp(1,"xyz");
    ========================== js
    function disp(x, y) {
        console.log(x);
        console.log(y);
    }
    disp("abc");
    disp(1, "xyz");
    ========================== 输出
    abc
    undefined
    1
    xyz
    

    例11 (构造函数)

    ========================== ts
    var myFunction = new Function("a", "b", "return a * b"); 
    var x = myFunction(4, 3); 
    console.log(x);
    ========================== js
    var myFunction = new Function("a", "b", "return a * b");
    var x = myFunction(4, 3);
    console.log(x);
    ========================== 输出
    12
    

    例12 (递归函数)

    ========================== ts
    function factorial(number) {
        if (number <= 0) {         // 停止执行
            return 1; 
        } else {     
            return (number * factorial(number - 1));     // 调用自身
        } 
    }; 
    console.log(factorial(6));      // 输出 720
    ========================== js
    function factorial(number) {
        if (number <= 0) { // 停止执行
            return 1;
        }
        else {
            return (number * factorial(number - 1)); // 调用自身
        }
    }
    ;
    console.log(factorial(6)); // 输出 720
    ========================== 输出
    720
    

    例13 (箭头函数)

    ========================== ts
    var foo = (x:number)=>10 + x 
    console.log(foo(100))      //输出结果为 110
    ========================== js
    var foo = function (x) { return 10 + x; };
    console.log(foo(100)); //输出结果为 110
    ========================== 输出
    110
    

    例14 (箭头函数2)

    ========================== ts
    var func = (x)=> { 
        if(typeof x=="number") { 
            console.log(x+" 是一个数字") 
        } else if(typeof x=="string") { 
            console.log(x+" 是一个字符串") 
        }  
    } 
    func(12) 
    func("Tom")
    ========================== js
    var func = function (x) {
        if (typeof x == "number") {
            console.log(x + " 是一个数字");
        }
        else if (typeof x == "string") {
            console.log(x + " 是一个字符串");
        }
    };
    func(12);
    func("Tom");
    ========================== 输出
    12 是一个数字
    Tom 是一个字符串
    

    例15 (箭头函数3 ()为可选)

    ========================== ts
    var display = x => { 
        console.log("输出为 "+x) 
    } 
    display(12)
    ========================== js
    var display = function (x) {
        console.log("输出为 " + x);
    };
    display(12);
    ========================== 输出
    12
    

    例16 (箭头函数4 无参)

    ========================== ts
    var disp =()=> { 
        console.log("Function invoked"); 
    } 
    disp();
    ========================== js
    var disp = function () {
        console.log("调用函数");
    };
    disp();
    ========================== 输出
    调用函数
    
    1. 命名空间(解决重名问题)
    命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。
    
    // 位于SomeFileName.ts文件中
    namespace SomeNameSpaceName { 
       export interface ISomeInterfaceName {      }  
       export class SomeClassName {      }  
    }
    
    // 位于SomeFileName2.ts文件中
    /// <reference path = "SomeFileName.ts" />
    namespace SomeNameSpaceName2 { 
      SomeNameSpaceName.SomeClassName;
    }
    
    命名空间支持嵌套 (即可以将命名空间定义在另外一个命名空间里头)。
    
    namespace namespace_name1 { 
        export namespace namespace_name2 {
            export class class_name {    } 
        } 
    }
    

    例1

    ========================== Person.ts
    namespace Running { 
        export interface Person { 
           run(); 
        }
    }
    ========================== Teacher.ts文件
    /// <reference path = "Person.ts" />
    namespace Running { 
        export class Teacher implements Person { 
           public run() { 
              console.log("Teacher run"); 
           } 
        }
    }
    ========================== Student.ts
    /// <reference path = "Person.ts" />
    namespace Running { 
        export class Student implements Person { 
           public run() { 
              console.log("Student run"); 
           } 
        }
    }
    ========================== TestPerson.ts文件
    /// <reference path = "Person.ts" />
    /// <reference path = "Student.ts" />
    /// <reference path = "Teacher.ts" />
    
     
    function func(personM: Running.Person) {
       personM.run(); 
    } 
     
    func(new Running.Teacher()); 
    func(new Running.Student());
    
    ========================== js
    tsc --out test.js TestPerson.ts   生成的test.js文件如下:
    
    /// <reference path = "Person.ts" />
    var Running;
    (function (Running) {
        var Student = /** @class */ (function () {
            function Student() {
            }
            Student.prototype.run = function () {
                console.log("Student run");
            };
            return Student;
        }());
        Running.Student = Student;
    })(Running || (Running = {}));
    /// <reference path = "Person.ts" />
    var Running;
    (function (Running) {
        var Teacher = /** @class */ (function () {
            function Teacher() {
            }
            Teacher.prototype.run = function () {
                console.log("Teacher run");
            };
            return Teacher;
        }());
        Running.Teacher = Teacher;
    })(Running || (Running = {}));
    /// <reference path = "Person.ts" />
    /// <reference path = "Student.ts" />
    /// <reference path = "Teacher.ts" />
    function func(personM) {
        personM.run();
    }
    func(new Running.Teacher());
    func(new Running.Student());
    ========================== 输出
    Teacher run
    Student run
    

    例2

    ========================== Person.ts
    namespace Running { 
        export namespace Eatting { 
            export class Person { 
               public run(meter:number){
                  return meter*1000;
               } 
            }
        }
    }
    ========================== TestPerson.ts
    /// <reference path = "Person.ts" />
     
    var personM = new Running.Eatting.Person(); 
    console.log(personM.run(5));
    ========================== js
    tsc --out test.js TestPerson.ts   生成的test.js文件如下:
    
    var Running;
    (function (Running) {
        var Eatting;
        (function (Eatting) {
            var Person = /** @class */ (function () {
                function Person() {
                }
                Person.prototype.run = function (meter) {
                    return meter * 1000;
                };
                return Person;
            }());
            Eatting.Person = Person;
        })(Eatting = Running.Eatting || (Running.Eatting = {}));
    })(Running || (Running = {}));
    /// <reference path = "Person.ts" />
    var personM = new Running.Eatting.Person();
    console.log(personM.run(5));
    ========================== 输出
    5000
    
    1. 模块
    定义在模块内的变量、函数和类等在模块外是不可见的,使用export可以导出它们。
    两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。
    模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。
    
    // 文件名 : PersonInterface.ts 
    export interface PersonInterface { 
       // 代码部分
    }
    
    // 文件名 : Teacher.ts 
    import personInterfaceRef = require("./PersonInterface");
    

    ========================== Person.ts
    export interface Person { 
       run(); 
    }
    ========================== Teacher.ts
    import person = require("./Person"); 
    export class Teacher implements person.Person { 
       public run() { 
          console.log("Teacher run"); 
       } 
    }
    ========================== Student.ts
    import person = require("./Person"); 
    export class Student implements person.Person { 
       public run() { 
          console.log("Student run"); 
       } 
    }
    ========================== TestPerson.ts
    import person = require("./Person"); 
    import teacher = require("./Teacher"); 
    import student = require("./Student"); 
    
     
    function func(personM: person.Person) {
       personM.run(); 
    } 
     
    func(new teacher.Teacher()); 
    func(new student.Student());
    
    ==========================  js
    编译方式1  tsc --module amd TestPerson.ts
    
    生成的Person.js文件
    define(["require", "exports"], function (require, exports) {
        "use strict";
        exports.__esModule = true;
    });
    
    生成的Teacher.js文件
    define(["require", "exports"], function (require, exports) {
        "use strict";
        exports.__esModule = true;
        var Teacher = /** @class */ (function () {
            function Teacher() {
            }
            Teacher.prototype.run = function () {
                console.log("Teacher run");
            };
            return Teacher;
        }());
        exports.Teacher = Teacher;
    });
    
    生成的Student.js文件
    define(["require", "exports"], function (require, exports) {
        "use strict";
        exports.__esModule = true;
        var Student = /** @class */ (function () {
            function Student() {
            }
            Student.prototype.run = function () {
                console.log("Student run");
            };
            return Student;
        }());
        exports.Student = Student;
    });
    
    生成的TestPerson.js文件
    define(["require", "exports", "./Teacher", "./Student"], function (require, exports, teacher, student) {
        "use strict";
        exports.__esModule = true;
        function func(personM) {
            personM.run();
        }
        func(new teacher.Teacher());
        func(new student.Student());
    });
    
    ==========================  js
    编译方式2 tsc --module commonjs TestPerson.ts 
    
    生成的Person.js文件
    "use strict";
    exports.__esModule = true;
    
    生成的Teacher.js文件
    "use strict";
    exports.__esModule = true;
    var Teacher = /** @class */ (function () {
        function Teacher() {
        }
        Teacher.prototype.run = function () {
            console.log("Teacher run");
        };
        return Teacher;
    }());
    exports.Teacher = Teacher;
    
    生成的Student.js文件
    "use strict";
    exports.__esModule = true;
    var Student = /** @class */ (function () {
        function Student() {
        }
        Student.prototype.run = function () {
            console.log("Student run");
        };
        return Student;
    }());
    e
    
    生成的TestPerson.js文件
    "use strict";
    exports.__esModule = true;
    var teacher = require("./Teacher");
    var student = require("./Student");
    function func(personM) {
        personM.run();
    }
    func(new teacher.Teacher());
    func(new student.Student());
    
    1. 声明文件
      TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。
      为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。
    
    例1 
    jQuery('#foo');
    
    在ts中使用jQuery报错 hello.ts:25:1 - error TS2304: Cannot find name 'jQuery'.
    解决如下:
    
    1. 创建hello.d.ts
    declare var jQuery: (selector: string) => any;
    
    2. hello.js文件顶部添加
    /// <reference path = "hello.d.ts"/>
    

    目前很多流行的三方库都有现成的声明文件,如 jQuery

    例2
    
    创建customThird.js文件(自定义三方库)
    var Third;  
    (function(Third) {
        var Person = (function () { 
            function Person() { 
            } 
        })
        Person.prototype.run = function (limit) {
            var sum = 0; 
     
            for (var i = 0; i <= limit; i++) { 
                sum = sum + i; 
            }
            return sum; 
        }
        Third.Person = Person; 
        return Person; 
    })(Third || (Third = {})); 
    var person = new Third.Person();
    
    
    1. 创建Person.d.ts
    declare module Third { 
       export class Person { 
          run(limit:number) : number; 
       }
    }
    
    
    2. hello.js中加
    /// <reference path = "Person.d.ts" />
    
    var person = new Third.Person();
    console.log(person.run(10)); // 只能传数字类型
    
    
    3. 编译
    tsc hello.ts
    
    编译不报错则成功
    
    1. 数据类型
    数据类型 关键字 说明
    任意类型 any 用于类型不明确的变量(跳过编译阶段的类型检查)
    数字类型 number 双精度64位浮点值。6、0b1010、0o744、0xf00d
    字符串类型 string 字符串。双引号(“”)、单引号(‘’)包含文本,反引号(``)包含多行文本和内嵌表达式${name}
    布尔类型 boolean true 和 false
    数组类型 声明变量为数组
    元组类型 已知元素数量和类型的数组。各元素的类型不必相同,对应位置的类型需要相同。
    枚举 enum 一组相关联类型。
    void void 标识方法返回值的类型,表示该方法没有返回值。function hello(): void {}
    null null 表示对象值缺失(一个空对象引用)。
    undefined undefined 用于初始化变量为一个未定义的值(一个没有设置值的变量)。
    never never never 是其它任何类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
    注意:
      1. TypeScript 和 JavaScript 没有整数类型
    

    string 例子

    let name: string = "cx";
    let years: number = 2020;
    let words: string = `hello ${ name } , ${ years } 年`;
    

    数组类型 例子

    // 在元素类型后面加上[]
    let arr: number[] = [1, 2];
    
    // 或者使用数组泛型
    let arr: Array<number> = [1, 2];
    

    元组类型 例子

    let x: [string, number];
    x = ['cx', 1];    // 运行正常
    x = [1, 'cx'];    // 报错
    console.log(x[0]);    // 输出 cx
    

    枚举 例子

    enum Color {Red, Green, Blue};
    let c: Color = Color.Blue;
    console.log(c);    // 输出 2
    

    任意类型(any)

    3种情形
      1、变量的值动态改变,比如来自用户的输入
        let x: any = 1;    // 数字类型
        x = 'hello';    // 字符串类型
        x = false;    // 布尔类型
      2、跳过编译阶段的类型检查
      3、定义存储各种类型数据的数组时
        let arrayList: any[] = [1, false, 'fine'];
    

    Null 和 Undefined

    Null 和 Undefined 是其他任何类型(包括 void)的子类型,可以赋值给其它任何类型。但是TypeScript中启用严格的空校验(--strictNullChecks)特性,使得null 和 undefined 只能被赋值给 void 或本身对应的类型。可以用 | 来支持多种类型。
    
    
    typeof 检测 null 返回是 object
    typeof 检测 undefined 返回是 undefined
    
    
    let x: number;
    let x2: number | null | undefined;
    x = 1;             // 运行正确
    x = undefined;     // 运行错误
    x = null;          // 运行错误
    x2 = 1;            // 运行正确
    x2 = undefined;    // 运行正确
    x2 = null;         // 运行正确
    

    never

    never类型的变量只能被赋值 never类型的值
    
    let x: never;
    let y: number;
    
    // 运行错误,数字类型不能转为 never 类型
    x = 123;
    
    // 运行正确,never 类型可以赋值给 never类型
    x = (()=>{ throw new Error('exception')})();
    
    // 运行正确,never 类型可以赋值给 数字类型
    y = (()=>{ throw new Error('exception')})();
    
    // 返回值为 never 的函数可以是抛出异常的情况
    function error(message: string): never {
        throw new Error(message);
    }
    
    // 返回值为 never 的函数可以是无法被执行到的终止点的情况
    function loop(): never {
        while (true) {}
    }
    
    1. 保留关键字
    保留
    break as catch switch
    case if throw else
    var number string get
    module type instanceof typeof
    public private enum export
    finally for while void
    null super this new
    in return true false
    any extends static let
    package implements interface function
    new try yield const
    continue do

    2. 语句

    1. 条件语句
    用于基于不同的条件来执行不同的流程
    
    if(boolean_expression){
      # 如果布尔表达式 boolean_expression为 true,则 if 语句内的代码块将被执行。否则不被执行。
    }
    
    
    if(boolean_expression){
       # 在布尔表达式 boolean_expression 为 true 执行
    }else{
       # 在布尔表达式 boolean_expression 为 false 执行
    }
    
    
    if(boolean_expression 1){
        # 在布尔表达式 boolean_expression 1 为 true 执行
    }
    else if( boolean_expression 2){
        # 在布尔表达式 boolean_expression 2 为 true 执行
    }
    else{
        # 布尔表达式的条件都为 false 时执行
    }
    
    
    expression 是一个常量表达式,必须是一个整型或枚举类型
    switch(expression){
        case constant-expression  :
           statement(s);
           break; /* 可选的 */
        case constant-expression  :
           statement(s);
           break; /* 可选的 */
      
        /* 您可以有任意数量的 case 语句 */
        default : /* 可选的 */
           statement(s);
    }
    
    

    if(boolean_expression){}

    ========================== ts
    var  num:number = 5
    if (num > 0) { 
       console.log("数字是正数") 
    }
    ========================== js
    var num = 5;
    if (num > 0) {
        console.log("数字是正数");
    }
    ========================== 输出
    数字是正数
    

    if(boolean_expression){}else{}

    ========================== ts
    var num:number = 12; 
    if (num % 2==0) { 
        console.log("偶数"); 
    } else {
        console.log("奇数"); 
    }
    ========================== js
    var num = 12;
    if (num % 2 == 0) {
        console.log("偶数");
    }
    else {
        console.log("奇数");
    }
    ========================== 输出
    偶数
    

    if(boolean_expression){}else if(boolean_expression2){}else{}

    ========================== ts
    var num:number = 2 
    if(num > 0) { 
        console.log(num+" 是正数") 
    } else if(num < 0) { 
        console.log(num+" 是负数") 
    } else { 
        console.log(num+" 不是正数也不是负数") 
    }
    ========================== js
    var num = 2;
    if (num > 0) {
        console.log(num + " 是正数");
    }
    else if (num < 0) {
        console.log(num + " 是负数");
    }
    else {
        console.log(num + " 不是正数也不是负数");
    }
    ========================== 输出
    2 是正数
    

    switch

    ========================== ts
    var grade:string = "A"; 
    switch(grade) { 
        case "A": { 
            console.log("优"); 
            break; 
        } 
        case "B": { 
            console.log("良"); 
            break; 
        } 
        case "C": {
            console.log("及格"); 
            break;    
        } 
        case "D": { 
            console.log("不及格"); 
            break; 
        }  
        default: { 
            console.log("非法输入"); 
            break;              
        } 
    }
    ========================== js
    var grade = "A";
    switch (grade) {
        case "A": {
            console.log("优");
            break;
        }
        case "B": {
            console.log("良");
            break;
        }
        case "C": {
            console.log("及格");
            break;
        }
        case "D": {
            console.log("不及格");
            break;
        }
        default: {
            console.log("非法输入");
            break;
        }
    }
    ========================== 输出
    优
    
    1. 循环语句
    基于临界条件,循环执行某一代码块
    

    for ( init; condition; increment ){}

    for ( init; condition; increment ){
        statement(s);
    }
    
        1. init 会首先被执行,且只会执行一次。这一步可以声明并初始化任何循环控制变量。此处可以不写任何语句。
        2. 接下来,会判断 condition。如果为 true,则执行循环主体。如果为 false,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
        3. 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许更新循环控制变量。此处可以不写任何语句。
        4. 条件再次被判断。如果为 true,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为 false 时,for 循环终止。
    
    
    例1
    ========================== ts
    var num:number = 5; 
    var i:number; 
    var factorial = 1; 
     
    for(i = num;i>=1;i--) {
       factorial *= i;
    }
    console.log(factorial);
    ========================== js
    var num = 5;
    var i;
    var factorial = 1;
    for (i = num; i >= 1; i--) {
        factorial *= i;
    }
    console.log(factorial);
    ========================== 输出
    120
    

    for (var val in list) {}

    ========================== ts
    var j:any; 
    var n:any = "a b c"; 
     
    for(j in n) {
        console.log(n[j]);  
    }
    ========================== js
    var j;
    var n = "a b c";
    for (j in n) {
        console.log(n[j]);
    }
    ========================== 输出
    a
     
    b
     
    c
    

    for (let entry of someArray) {}

    ========================== ts
    let someArray = [1, "string", false];
     
    for (let entry of someArray) {
        console.log(entry); // 1, "string", false
    }
    ========================== js
    var someArray = [1, "string", false];
    for (var _i = 0, someArray_1 = someArray; _i < someArray_1.length; _i++) {
        var entry = someArray_1[_i];
        console.log(entry); // 1, "string", false
    }
    ========================== 输出
    1
    string
    false
    

    list.forEach((val, idx, array) => {}

    ========================== ts
    let list = [4, 5, 6];
    list.forEach((val, idx, array) => {
        // val: 当前值
        // idx:当前index
        // array: Array
        console.log("val: "+val+"  idx"+idx+"   array"+array);
    });
    ========================== js
    var list = [4, 5, 6];
    list.forEach(function (val, idx, array) {
        // val: 当前值
        // idx:当前index
        // array: Array
        console.log("val: " + val + "  idx" + idx + "   array" + array);
    });
    ========================== 输出
    val: 4  idx0   array4,5,6
    val: 5  idx1   array4,5,6
    val: 6  idx2   array4,5,6
    

    list.every((val, idx, array) => {}

    ========================== ts
    let list = [4, 5, 6];
    list.every((val, idx, array) => {
        // val: 当前值
        // idx:当前index
        // array: Array
        return true; // Continues
        // Return false will quit the iteration
    });
    ========================== js
    var list = [4, 5, 6];
    list.every(function (val, idx, array) {
        // val: 当前值
        // idx:当前index
        // array: Array
        console.log("val: " + val + "  idx" + idx + "   array" + array);
        return true; // Continues
        // Return false will quit the iteration
    });
    ========================== 输出
    val: 4  idx0   array4,5,6
    val: 5  idx1   array4,5,6
    val: 6  idx2   array4,5,6
    

    while

    while 语句在给定条件为 true 时,重复执行语句或语句组。循环主体执行之前会先测试条件。
    
    while(condition)
    {
       statement(s);
    }
    
    ========================== ts
    var num:number = 5; 
    var factorial:number = 1; 
     
    while(num >=1) { 
        factorial = factorial * num; 
        num--; 
    } 
    console.log("5 的阶乘为:"+factorial);
    ========================== js
    var num = 5;
    var factorial = 1;
    while (num >= 1) {
        factorial = factorial * num;
        num--;
    }
    console.log("5 的阶乘为:" + factorial);
    ========================== 输出
    5 的阶乘为:120
    

    do...while 先执行一遍循环,再检查条件去循环

    do
    {
       statement(s);
    }while( condition );
    
    
    例1
    ========================== ts
    var n:number = 3;
    do { 
        console.log(n); 
        n--; 
    } while(n>=0);
    ========================== js
    var n = 3;
    do {
        console.log(n);
        n--;
    } while (n >= 0);
    ========================== 输出
    3
    2
    1
    0
    

    break

    break;
    
    当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。也可用在switch语句中。
    

    continue

    continue;
    
    终止本次循环,开始下一次循环
    

    无限循环

    for(;;) { 
    }
    
    while(true) { 
       // 语句
    } 
    

    3. 面向对象

    TypeScript 是一种面向对象的编程语言

    类:一个模板,它描述了一类对象共有的状态(属性)和行为(方法)。是一个抽象的概念。
    对象:对象是类的一个具体实例(拥有状态和行为)。
    
    例
      狗类是一个类(状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等)
      小黄是一条狗,是狗类的一个实例。
    

    ========================== ts
    class Teacher {
        fullName: string;
        constructor(public firstName, public middleInitial, public lastName) {
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
        name():void { 
          console.log("hello "+this.fullName); 
        } 
    }
    let teacher = new Teacher("chen", "M.", "Teacher");
    teacher.name();
    ========================== js
    var Teacher = /** @class */ (function () {
        function Teacher(firstName, middleInitial, lastName) {
            this.firstName = firstName;
            this.middleInitial = middleInitial;
            this.lastName = lastName;
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
        Teacher.prototype.name = function () {
            console.log("hello " + this.fullName);
        };
        return Teacher;
    }());
    var teacher = new Teacher("chen", "M.", "Teacher");
    teacher.name();
    
    1. 接口
    接口是一系列抽象方法的声明 (由遵守该接口的类去实现)
    
    interface interface_name { 
    }
    

    例1

    ========================== ts
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    function greeter(person: Person) {
        return "just, " + person.firstName + "  " + person.lastName;
    }
    
    let person = { firstName: "hello", lastName: "world" };
    
    document.body.innerHTML = greeter(person);
    ========================== js
    function greeter(person) {
        return "just, " + person.firstName + "  " + person.lastName;
    }
    var person = { firstName: "hello", lastName: "world" };
    document.body.innerHTML = greeter(person);
    

    例2

    ========================== ts
    interface Person { 
        name:string,
        sex:string,
        sayHello:()=>string,
    }
    var person:Person = {
        name:"cx",
        sex:"boy",
        sayHello:():string=>{
            return "hell world";
        }
    }
    console.log("Person 对象");
    console.log(person.name);
    console.log(person.sex);
    console.log(person.sayHello()); 
    ========================== js
    var person = {
        name: "cx",
        sex: "boy",
        sayHello: function () {
            return "hell world";
        }
    };
    console.log("Person 对象");
    console.log(person.name);
    console.log(person.sex);
    console.log(person.sayHello());
    ========================== 输出
    Person 对象
    cx
    boy
    hell world
    

    例3(接口和联合类型)

    ========================== ts
    interface Person { 
        name:string; 
        say:string|string[]|(()=>string); 
    } 
     
    // say 是字符串
    var person:Person = {
        name:"test1",
        say:"Hello",
    }; 
    console.log(person.say);  
     
     
    // say 是字符串数组
    person = {
        name:"test1",
        say:["Hello","World"]
    }; 
    console.log(person.say[0]); 
    console.log(person.say[1]);  
     
    
    // say 是一个函数表达式
    person = {
        name:"test1",
        say:()=>{
            return "Hello World!";
        }
    }; 
    var func:any = person.say; 
    console.log(func());
    ========================== js
    // say 是字符串
    var person = {
        name: "test1",
        say: "Hello"
    };
    console.log(person.say);
    // say 是字符串数组
    person = {
        name: "test1",
        say: ["Hello", "World"]
    };
    console.log(person.say[0]);
    console.log(person.say[1]);
    // say 是一个函数表达式
    person = {
        name: "test1",
        say: function () {
            return "Hello World!";
        }
    };
    var func = person.say;
    console.log(func());
    ========================== 输出
    Hello
    Hello
    World
    Hello World!
    

    例4(接口和数组)

    接口中可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串。
    
    interface PersonList { 
        [index:number]:string,
    }
    interface AgeList { 
        [index:string]:number,
    }
    
    var personList:PersonList = ["ZhouXingChi","LiuDeHua","HuangBo",8];  // 8这里提示错误
    
    var ageList:AgeList;
    ageList["ZhouXingChi"] = 66;
    ageList[2] = 66;
    ageList[3] = "66";      // "66"  这里提示错误
    

    例5 (接口继承)

    扩展其他接口
    
    Child_interface_name extends super_interface_name,super_interface2_name
    
    ========================== ts
    interface Animal { 
        sex:string,
    }
    interface Person extends Animal{ 
        name:string,
    }
    
    var person:Person = {name:"cx",sex:"boy"};
    console.log("name: "+person.name+" sex:"+person.sex);
    ========================== js
    var person = { name: "cx", sex: "boy" };
    console.log("name: " + person.name + " sex:" + person.sex);
    ========================== 输出
    name: cx sex:boy
    
    ========================== ts
    interface Person { 
        name:string,
    }
    interface Animal { 
        sex:string,
    }
    interface Engineer extends Person,Animal { 
    }
    
    var engineer = <Engineer>{};
    engineer.name = "cx";
    engineer.sex = "boy";
    
    console.log("name: "+engineer.name+" sex:"+engineer.sex);
    ========================== js
    var engineer = {};
    engineer.name = "cx";
    engineer.sex = "boy";
    console.log("name: " + engineer.name + " sex:" + engineer.sex);
    ========================== 输出
    name: cx sex:boy
    
    类:一个模板,它描述了一类对象共有的状态(属性)和行为(方法)。是一个抽象的概念。
    定义类的关键字为 class,后面紧跟类名,类可以包含以下(类的数据成员):
        1. 字段 (属性)
        2. 构造函数 (用于实例化对象)
        3. 方法 
    
    // 创建类
    class class_name { // 类作用域
        // 字段 
        name:string; 
    
        // 构造函数 
        constructor(name:string) { 
            this.name = name; 
        }  
    
        // 方法 
        run():void { 
            console.log(this.name+" run 100000 meters"); 
        } 
    }
    
    // 创建实例化对象
    var object_name = new class_name("cx"); 
    // 使用对象的属性
    console.log("name : "+object_name.name); 
    // 使用对象的方法  
    object_name.run(); 
    

    继承

    class child_class_name extends parent_class_name
    
    子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承
    只能继承一个类,不支持继承多个类
    
    ========================== ts
    class Person {
       sex:string; 
       
       constructor(sex:string) { 
          this.sex = sex; 
       } 
    }
    class Teacher extends Person{
        run():void { 
            console.log("teacher run"); 
        } 
    }
    var teacher=new Teacher("boy");
    teacher.run();
    ========================== js
    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 Person = /** @class */ (function () {
        function Person(sex) {
            this.sex = sex;
        }
        return Person;
    }());
    var Teacher = /** @class */ (function (_super) {
        __extends(Teacher, _super);
        function Teacher() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        Teacher.prototype.run = function () {
            console.log("teacher run");
        };
        return Teacher;
    }(Person));
    var teacher = new Teacher("boy");
    teacher.run();
    ========================== 输出
    teacher run
    

    重写

    子类重写继承自父类的方法
    
    ========================== ts
    class Person {
        run():void { 
            console.log("person run"); 
        } 
    }
    class Teacher extends Person{
        run():void { 
            super.run();
            console.log("teacher run"); 
        } 
    }
    var teacher=new Teacher();
    teacher.run();
    ========================== js
    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 Person = /** @class */ (function () {
        function Person() {
        }
        Person.prototype.run = function () {
            console.log("person run");
        };
        return Person;
    }());
    var Teacher = /** @class */ (function (_super) {
        __extends(Teacher, _super);
        function Teacher() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        Teacher.prototype.run = function () {
            _super.prototype.run.call(this);
            console.log("teacher run");
        };
        return Teacher;
    }(Person));
    var teacher = new Teacher();
    teacher.run();
    ========================== 输出
    person run
    teacher run
    

    static 关键字

    static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。
    
    ========================== ts
    class Person {
        static handNum:number;
        static hello():void{
            console.log("handNum 值为 "+ Person.handNum); 
        }
    }
    Person.handNum=2;
    Person.hello();
    ========================== js
    var Person = /** @class */ (function () {
        function Person() {
        }
        Person.hello = function () {
            console.log("handNum 值为 " + Person.handNum);
        };
        return Person;
    }());
    Person.handNum = 2;
    Person.hello();
    ========================== 输出
    handNum 值为 2
    

    instanceof 运算符

    instanceof 运算符用于判断对象是否是指定的类型,如果是返回 true,否则返回 false。
    
    ========================== ts
    class Teacher {
    }
    var teacher = new Teacher();
    var isTeacher = teacher instanceof Teacher; 
    console.log("teacher对象是Teacher类的实例吗? " + isTeacher);
    ========================== js
    var Teacher = /** @class */ (function () {
        function Teacher() {
        }
        return Teacher;
    }());
    var teacher = new Teacher();
    var isTeacher = teacher instanceof Teacher;
    console.log("teacher对象是Teacher类的实例吗? " + isTeacher);
    ========================== 输出
    teacher对象是Teacher类的实例吗? true
    

    访问控制修饰符

    TypeScript使用访问控制符来保护对类、变量、方法和构造方法的访问。 支持3种不同的访问权限:
        1. public(默认) : 公有,可以在任何地方被访问。
        2. protected : 受保护,可以被其自身以及其子类和父类访问。
        3. private : 私有,只能被其定义所在的类访问。
    
    
    class Teacher {
        private name:string; 
        sex:string;
        constructor(name:string,sex:string) { 
            this.name = name; 
            this.sex = sex;
        }  
    }
    var teacher = new Teacher("cx","boy");
    console.log("sex : "+teacher.sex); 
    console.log("name : "+teacher.name);   // 编译报错  Property 'name' is private and only accessible within class 'Teacher'
    

    类和接口

    类可以实现接口 (使用关键字 implements)
    
    ========================== ts
    interface Person { 
       name:string; 
       run(); 
    }
    
    class Teacher {
        name:string; 
        sex:string;
     
        constructor(name:string,sex:string) { 
            this.name = name; 
            this.sex = sex;
        }  
    
        run():void { 
            console.log(this.name+" run 100000 meters"); 
        } 
    }
    
    var teacher = new Teacher("cx","boy");
    console.log("name : "+teacher.name); 
    teacher.run(); 
    ========================== ts
    var Teacher = /** @class */ (function () {
        function Teacher(name, sex) {
            this.name = name;
            this.sex = sex;
        }
        Teacher.prototype.run = function () {
            console.log(this.name + " run 100000 meters");
        };
        return Teacher;
    }());
    var teacher = new Teacher("cx", "boy");
    console.log("name : " + teacher.name);
    teacher.run();
    
    例1
    
    ========================== ts
    class Person {
    }
    ========================== js
    var Person = /** @class */ (function () {
        function Person() {
        }
        return Person;
    }());
    
    例2
    
    ========================== ts
    class Person {
        // 字段 
        name:string; 
     
        // 构造函数 
        constructor(name:string) { 
            this.name = name; 
        }  
     
        // 方法 
        run():void { 
            console.log(this.name+" run 100000 meters"); 
        } 
    }
    var person = new Person("cx");
    console.log("name : "+person.name); 
    person.run(); 
    ========================== js
    var Person = /** @class */ (function () {
        // 构造函数 
        function Person(name) {
            this.name = name;
        }
        // 方法 
        Person.prototype.run = function () {
            console.log(this.name + " run 100000 meters");
        };
        return Person;
    }());
    var person = new Person("cx");
    console.log("name : " + person.name);
    person.run();
    ========================== 输出
    name : cx
    cx run 100000 meters
    
    例3
    
    ========================== ts
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    class Teacher {
        fullName: string;
        constructor(public firstName, public middleInitial, public lastName) {
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
    }
    
    function greeter(person: Person) {
        return "just, " + person.firstName + "  " + person.lastName;
    }
    
    let teacher = new Teacher("chen", "M.", "Teacher");
    
    document.body.innerHTML = greeter(teacher);
    ========================== js
    var Teacher = /** @class */ (function () {
        function Teacher(firstName, middleInitial, lastName) {
            this.firstName = firstName;
            this.middleInitial = middleInitial;
            this.lastName = lastName;
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
        return Teacher;
    }());
    function greeter(person) {
        return "just, " + person.firstName + "  " + person.lastName;
    }
    var teacher = new Teacher("chen", "M.", "Teacher");
    document.body.innerHTML = greeter(teacher);
    
    1. 对象
    对象是类的一个具体实例(拥有状态和行为)。包含一组键值对的实例, 值可以是标量、函数、数组、对象等。
    
    var object_name = { 
        key1: "value1", // 标量
        key2: function() {
            // 函数
        }, 
        key3:["content1", "content2"], //集合
        key4:{     // 对象
          key1: "value1",
        }
    }
    
    鸭子类型(英语:duck typing)是动态类型的一种风格,是多态(polymorphism)的一种形式。
    在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。
    
    interface Person {    
        name:string, 
        sex:string,
    }
    function func(obj:Person):Person { 
        console.log("name :"+obj.name); 
        console.log("sex :"+obj.sex); 
        return {name:"China "+obj.name,sex:obj.sex};
    } 
    func({sex:"boy"});  // 报错,Property 'name' is missing
    func({name:"cx",sex:"boy"});
    

    例1

    ========================== ts
    var persson = { 
       name:"cx", 
       sex:"boy",
       run:function(){} // 类型模板,需在这里声明
    }; 
    // 访问对象的属性
    console.log(persson.name); 
    console.log(persson.sex);
    // 方法实现
    persson.run = function () {
        console.log(persson.name+" run 100000000 meters");
    };
    // 访问对象的方法
    persson.run();
    // 对象作参
    var func = function(obj: { name:string, sex:string }) { 
        console.log("name :"+obj.name); 
        console.log("sex :"+obj.sex); 
    } 
    func(persson);
    ========================== js
    var persson = {
        name: "cx",
        sex: "boy",
        run: function () { } // 类型模板,需在这里声明
    };
    // 访问对象的属性
    console.log(persson.name);
    console.log(persson.sex);
    // 方法实现
    persson.run = function () {
        console.log(persson.name + " run 100000000 meters");
    };
    // 访问对象的方法
    persson.run();
    // 对象作参
    var func = function (obj) {
        console.log("name :" + obj.name);
        console.log("sex :" + obj.sex);
    };
    func(persson);
    ========================== 输出
    cx
    boy
    cx run 100000000 meters
    name :cx
    sex :boy
    

    4. String、Number、数组、元组

    1. String 字符串
    var txt = new String("string");
    
    var txt = "string";
    
    1. length 长度
    var uname = new String("Hello World") 
    console.log("Length "+uname.length)  // 输出 11
    
    1. constructor 构造函数
    var str = new String( "This is string" ); 
    console.log("str.constructor is:" + str.constructor)    // function String() { [native code] }
    
    1. charAt 获取指定位置的字符
    var str = new String("Hello"); 
    console.log("str.charAt(0) 为:" + str.charAt(0)); // H
    
    1. charCodeAt 获取指定位置的字符的Unicode编码
    var str = new String("RUN"); 
    console.log("str.charCodeAt(0) 为:" + str.charCodeAt(0)); // 82
    
    1. concat 返回一个新的拼接后的字符串
    var str1 = new String( "RUNOOB" ); 
    var str2 = new String( "GOOGLE" ); 
    var str3 = str1.concat( str2 ); 
    console.log("str1 + str2 : "+str3) // RUNOOBGOOGLE
    
    1. indexOf 返回指定字符/字符串首次出现的位置
    var str1 = new String( "Hello Hi" ); 
    
    var index = str1.indexOf( "H" ); 
    console.log("查找的字符串位置 :" + index );  // 0
    
    1. lastIndexOf 返回指定字符/字符串最后一次出现的位置
    var str1 = new String( "This is string one and again string" ); 
    var index = str1.lastIndexOf( "string" );
    console.log("lastIndexOf 查找到的最后字符串位置 :" + index ); // 29
    
    1. toUpperCase 全部转大写
    var str = "Hello World"; 
    console.log(str.toUpperCase( ));  // HELLO WORLD
    
    1. toLowerCase 全部转小写
    var str = "Hello World"; 
    console.log(str.toLowerCase( ));  // hello world
    
    1. substring 截取字符串(开始下标,结束下标)
    var str = "Hello World"; 
    console.log("(1,2): "    + str.substring(1,2));   // e
    
    1. substr 截取字符串(开始下标,长度)
    var str = "Hello World"; 
    console.log("(1,2): "    + str.substr(1,2));   // el
    
    1. split 分割为数组
    var str = "Apples are round, and apples are juicy."; 
    var splitted = str.split(" ", 3); 
    console.log(splitted)  // [ 'Apples', 'are', 'round,' ]
    
    1. slice 提取字符串的片断,并在新的字符串中返回被提取的部分
    
    
    1. search 检索与正则表达式相匹配的值
    var re = /apples/gi; 
    var str = "Apples are round, and apples are juicy.";
    if (str.search(re) == -1 ) { 
       console.log("Does not contain Apples" ); 
    } else { 
       console.log("Contains Apples" ); 
    } 
    
    1. replace 替换与正则表达式相匹配的值
    var re = /(\w+)\s(\w+)/; 
    var str = "zara ali"; 
    var newstr = str.replace(re, "$2, $1"); 
    console.log(newstr); // ali, zara
    
    1. match 查找一个或多个正则表达式的匹配
    var str="The rain in SPAIN stays mainly in the plain"; 
    var n=str.match(/ain/g);  // [ 'ain', 'ain', 'ain' ]
    
    1. localeCompare 用本地特定的顺序来比较两个字符串。
    var str1 = new String( "This is beautiful string" );
    var index = str1.localeCompare( "This is beautiful string");  
    console.log("localeCompare first :" + index );  // 0
    
    1. toLocaleLowerCase 据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射。
    var str = "Hello World"; 
    console.log(str.toLocaleLowerCase( ));  // hello world
    
    1. toLocaleUpperCase 据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射。
    var str = "Hello World"; 
    console.log(str.toLocaleUpperCase( ));  // HELLO WORLD
    
    1. toString 返回字符串
    var str = "Hello"; 
    console.log(str.toString( )); // Hello
    
    1. valueOf 返回指定字符串对象的原始值
    var str = new String("Hello World"); 
    console.log(str.valueOf());  // Hello World
    
    1. Number
    Number 对象是原始数值的包装对象。
    如果一个参数值不能转换为一个数字将返回 NaN (非数字值)
    
    var num = new Number(value);
    
    MAX_VALUE  表示最大的数
    MIN_VALUE  表示最小的正数
    -MIN_VALUE 表示最大的负数
    NaN  非数字值
    NEGATIVE_INFINITY  负无穷大,溢出时返回该值
    POSITIVE_INFINITY  正无穷大,溢出时返回该值
    prototype  Number 对象的静态属性。向对象添加属性和方法
    constructor  返回对创建此对象的 Number 函数的引用
    
    1. toExponential 把对象的值转换为指数计数法
    var num1 = 1225.30 
    var val = num1.toExponential(); 
    console.log(val) // 输出: 1.2253e+3
    
    1. toFixed 把数字转换为字符串,并对小数点指定位数
    var num3 = 177.234 
    console.log("num3.toFixed() 为 "+num3.toFixed())    // 输出:177
    console.log("num3.toFixed(2) 为 "+num3.toFixed(2))  // 输出:177.23
    console.log("num3.toFixed(6) 为 "+num3.toFixed(6))  // 输出:177.234000
    
    1. toPrecision 把数字格式化为指定的长度
    var num = new Number(7.123456); 
    console.log(num.toPrecision());  // 输出:7.123456 
    console.log(num.toPrecision(1)); // 输出:7
    console.log(num.toPrecision(2)); // 输出:7.1
    
    1. toLocaleString 把数字转换为字符串,使用本地数字格式顺序
    var num = new Number(177.1234); 
    console.log( num.toLocaleString());  // 输出:177.1234
    
    1. toString 把数字转换为字符串,使用指定的基数。数字的基数是 2 ~ 36 之间的整数。若省略该参数,则使用基数 10。
    var num = new Number(10); 
    console.log(num.toString());  // 输出10进制:10
    console.log(num.toString(2)); // 输出2进制:1010
    console.log(num.toString(8)); // 输出8进制:12
    
    1. valueOf 返回一个 Number 对象的原始数字值
    var num = new Number(10); 
    console.log(num.valueOf()); // 输出:10
    

    例1

    ========================== ts
    console.log("TypeScript Number 属性: "); 
    console.log("最大值为: " + Number.MAX_VALUE); 
    console.log("最小值为: " + Number.MIN_VALUE); 
    console.log("负无穷大: " + Number.NEGATIVE_INFINITY); 
    console.log("正无穷大:" + Number.POSITIVE_INFINITY);
    ========================== js
    console.log("TypeScript Number 属性: ");
    console.log("最大值为: " + Number.MAX_VALUE);
    console.log("最小值为: " + Number.MIN_VALUE);
    console.log("负无穷大: " + Number.NEGATIVE_INFINITY);
    console.log("正无穷大:" + Number.POSITIVE_INFINITY);
    ========================== 输出
    最大值为: 1.7976931348623157e+308
    最小值为: 5e-324
    负无穷大: -Infinity
    正无穷大:Infinity
    

    例2

    ========================== ts
    var month = 0 
    if( month<=0 || month >12) { 
        month = Number.NaN 
        console.log("月份是:"+ month) 
    } else { 
        console.log("输入月份数值正确。") 
    }
    ========================== js
    var month = 0;
    if (month <= 0 || month > 12) {
        month = Number.NaN;
        console.log("月份是:" + month);
    }
    else {
        console.log("输入月份数值正确。");
    }
    ========================== 输出
    月份是:NaN
    

    例3

    ========================== ts
    function employee(id:number,name:string) { 
        this.id = id 
        this.name = name 
    } 
     
    var emp = new employee(123,"admin") 
    employee.prototype.email = "admin@hello.com" 
     
    console.log("员工号: "+emp.id) 
    console.log("员工姓名: "+emp.name) 
    console.log("员工邮箱: "+emp.email)
    ========================== js
    function employee(id, name) {
        this.id = id;
        this.name = name;
    }
    var emp = new employee(123, "admin");
    employee.prototype.email = "admin@hello.com";
    console.log("员工号: " + emp.id);
    console.log("员工姓名: " + emp.name);
    console.log("员工邮箱: " + emp.email);
    ========================== 输出
    员工号: 123
    员工姓名: admin
    员工邮箱: admin@hello.com
    
    1. 数组
    存储一组相同类型的数据
    
    
    var array_name[:data type] = [val1,val2…valn];    // 声明并初始化
    
    var array_name[:datatype];        //声明 
    array_name = [val1,val2,valn..]   //初始化
    
    Array
    
    var array_name:number[] = new Array(5);  
    
    var array_name:string[] = new Array("cx","ZHouRunFa","LiuDeHua","LiXiaoLong"); 
    
    多维数组
    
    var arr_name:datatype[][]=[ [val1,val2,val3],[v1,v2,v3] ];
    

    方法

    1. concat 拼接2个数组,并返回拼接后的新数组
    var arr3 = arr1.concat(arr2); 
    
    1. every 检测数组中的每个元素是否都符合指定条件
    function isEnough(element, index, array) { 
        return (element >= 10); 
    } 
            
    var is_enough = [12, 5, 8, 130, 44].every(isEnough); 
    console.log("Test Value : " + is_enough ); // false
    
    1. some 检测数组中是否有元素符合指定条件
    function isEnough(element, index, array) { 
        return (element >= 10); 
    } 
            
    var is_enough = [12, 5, 8, 130, 44].some(isEnough); 
    console.log("Test Value : " + is_enough ); // true
    
    1. filter 返回数组中符合指定条件的元素
    function isEnough(element, index, array) { 
        return (element >= 10); 
    } 
            
    var enough_arr = [12, 5, 8, 130, 44].filter(isEnough); 
    console.log("Test Value : " + enough_arr ); // 12,130,44
    
    1. forEach 数组每个元素都执行一次回调函数
    function func(element) {
        console.log(element);
    } 
            
    var enough_arr = [12, 5, 8, 130, 44];
    enough_arr.forEach(func);
    
    1. map 通过指定函数处理数组的每个元素,并返回一个新的处理后数组
    var numbers = [1, 4, 9]; 
    var roots = numbers.map(Math.sqrt); 
    console.log("roots is : " + roots );  // 1,2,3
    
    1. indexOf 元素在数组中的下标
    var arr = [12, 5, 8, 130, 44];
    console.log("index is : " +  arr.indexOf(12));  // 0
    
    1. lastIndexOf() 返回指定字符串在数组最后面位置的下标
    var arr = [12, 5, 8, 130, 44 ,12];
    console.log("lastIndexOf is : " +  arr.lastIndexOf(12));  // 5
    
    1. join 拼接成字符串(默认以,拼接)
    var arr = new Array("orange", "mango", "banana", "sugar"); 
    var str = arr.join("-"); 
    console.log("Returned string is : " + str);  // orange-mango-banana-sugar
    
    1. pop 删除数组的最后一个元素, 并返回删除的元素
    var numbers = [1, 4, 9]; 
              
    var element = numbers.pop(); 
    console.log("element is : " + element );  // 9
              
    var element = numbers.pop(); 
    console.log("element is : " + element );  // 4
    
    1. push 向数组的末尾添加一个或更多元素,并返回新的长度
    var numbers = new Array(1, 4, 9); 
    var length = numbers.push(10); 
    console.log("new numbers is : " + numbers );  // 1,4,9,10 
    length = numbers.push(20); 
    console.log("new numbers is : " + numbers );  // 1,4,9,10,20
    
    1. reduce 将数组元素计算为一个值(从左到右)
    var total = [0, 1, 2, 3].reduce(function(a, b){ return a + b; }); 
    console.log("total is : " + total );  // 6
    
    1. reduceRight 将数组元素计算为一个值(从右到左)
    var total = [0, 1, 2, 3].reduceRight(function(a, b){ return a + b; }); 
    console.log("total is : " + total );  // 6
    
    1. reverse 反转数组的元素顺序
    var arr = [0, 1, 2, 3].reverse(); 
    console.log("Reversed array is : " + arr );  // 3,2,1,0
    
    1. shift 删除数组的第一个元素,并返回
    var arr_old = [10, 1, 2, 3];
    var arr = arr_old.shift(); 
    console.log("Shifted value is : " + arr );  // 10
    console.log("old value is : " + arr_old ); // 1,2,3
    
    1. slice 截取 (下标,长度)
    var arr = new Array("orange", "mango", "banana", "sugar"); 
    var new_arr = arr.slice(0,2); 
    console.log("Returned string is : " + new_arr[1]);  // banana
    
    1. sort 排序
    var arr = new Array("orange", "mango", "banana", "sugar"); 
    var sorted = arr.sort(); 
    console.log("Returned string is : " + sorted );  // banana,mango,orange,sugar
    
    1. splice 添加或删除元素(下标,删除的长度,新增的元素)
    var arr = ["orange", "mango", "banana", "sugar", "tea"];  
    var removed = arr.splice(2, 0, "water");  
    console.log("After adding 1: " + arr );    // orange,mango,water,banana,sugar,tea 
    console.log("removed is: " + removed);     // 空
              
    removed = arr.splice(3, 1);  
    console.log("After removing 1: " + arr );  // orange,mango,water,sugar,tea 
    console.log("removed is: " + removed);  // banana
    
    1. toString 数组转字符串(以,拼接)
    var arr = new Array("orange", "mango", "banana", "sugar");         
    var str = arr.toString(); 
    console.log("Returned string is : " + str );  // orange,mango,banana,sugar
    
    1. unshift 在数组开头添加一个或更多元素,并返回新的长度
    var arr = new Array("orange", "mango", "banana", "sugar"); 
    var length = arr.unshift("water"); 
    console.log("Returned array is : " + arr );  // water,orange,mango,banana,sugar 
    console.log("Length of the array is : " + length ); // 5
    

    例1

    ========================== ts
    var person:string[] = ["ZhouxingCHi","LiXiaoLong","LiuDeHua"];
    console.log(person[0]);
    ========================== js
    var person = ["ZhouxingCHi", "LiXiaoLong", "LiuDeHua"];
    console.log(person[0]);
    ========================== 输出
    ZhouxingCHi
    

    例2

    ========================== ts
    var person_arr:string[] = new Array("cx","ZHouRunFa","LiuDeHua","LiXiaoLong");
    
    var person:string[] = new Array(person_arr.length);
    for(var i = 0; i<person.length; i++) { 
            person[i] = person_arr[i]; 
            console.log(person[i]); 
    }
    
    var[a,b,c,d] = person_arr; // 数组结构
    console.log(a); 
    
    var index:any;
    for(index in person) { // 数组迭代
        console.log(person[index]);
    }
    
    var person_array:string[][] = [["cx","ZHouRunFa"],["LiuDeHua","LiXiaoLong"]];  // 多维数组
    console.log(person_array[0][0]); 
    
    // 作参
    function func(person:string[]) {
        for(var i = 0;i<person.length;i++) { 
            console.log(person[i]); 
        }  
    }  
    func(person);
    
    // 作函数返回值
    function func2():string[] { 
        return new Array("cx", "ZHouRunFa", "LiuDeHua", "LiXiaoLong");
    } 
    console.log(func2());
    ========================== js
    var person_arr = new Array("cx", "ZHouRunFa", "LiuDeHua", "LiXiaoLong");
    var person = new Array(person_arr.length);
    for (var i = 0; i < person.length; i++) {
        person[i] = person_arr[i];
        console.log(person[i]);
    }
    var a = person_arr[0], b = person_arr[1], c = person_arr[2], d = person_arr[3]; // 数组结构
    console.log(a);
    var index;
    for (index in person) { // 数组迭代
        console.log(person[index]);
    }
    var person_array = [["cx", "ZHouRunFa"], ["LiuDeHua", "LiXiaoLong"]]; // 多维数组
    console.log(person_array[0][0]);
    // 作参
    function func(person) {
        for (var i = 0; i < person.length; i++) {
            console.log(person[i]);
        }
    }
    func(person);
    // 作函数返回值
    function func2() {
        return new Array("cx", "ZHouRunFa", "LiuDeHua", "LiXiaoLong");
    }
    console.log(func2());
    ========================== 输出
    cx
    ZHouRunFa
    LiuDeHua
    LiXiaoLong
    cx
    cx
    ZHouRunFa
    LiuDeHua
    LiXiaoLong
    cx
    cx
    ZHouRunFa
    LiuDeHua
    LiXiaoLong
    [ 'cx', 'ZHouRunFa', 'LiuDeHua', 'LiXiaoLong' ]
    
    1. 元组
    存储一组不同类型的数据
    
    var tuple_name = [value1,value2,value3,…value n]
    tuple_name[index]    // 获取
    tuple_name[index] = value  // 更新
    tuple_name.push(value)  // 在最后面添加元素
    tuple_name.pop()  // 移除最后一个元素,并返回
    var [a,b] =  tuple_name  // 解构元组
    
    ========================== ts
    var person = ["ZhouxingCHi","LiXiaoLong",100];
    console.log(person[0]);
    console.log(person[2]);
    console.log("添加前元素个数:"+person.length);    // 返回元组的大小
    person.push("ZhouRunFa");
    console.log("添加后元素个数:"+person.length);    
    console.log("删除前元素个数:"+person.length);    
    console.log("删除元素:"+person.pop());  
    console.log("删除后元素个数:"+person.length);    
    person[0] = "cx";     // 更新元组元素
    console.log("元组中的第一个元素更新为:"+ person[0]);
    var [a,b,c] = person;
    console.log("a:"+a+"  b:"+b+"   c:"+c); 
    ========================== js
    var person = ["ZhouxingCHi", "LiXiaoLong", 100];
    console.log(person[0]);
    console.log(person[2]);
    console.log("添加前元素个数:" + person.length); // 返回元组的大小
    person.push("ZhouRunFa");
    console.log("添加后元素个数:" + person.length);
    console.log("删除前元素个数:" + person.length);
    console.log("删除元素:" + person.pop());
    console.log("删除后元素个数:" + person.length);
    person[0] = "cx"; // 更新元组元素
    console.log("元组中的第一个元素更新为:" + person[0]);
    var a = person[0], b = person[1], c = person[2];
    console.log("a:" + a + "  b:" + b + "   c:" + c);
    ========================== 输出
    ZhouxingCHi
    100
    添加前元素个数:3
    添加后元素个数:4
    删除前元素个数:4
    删除元素:ZhouRunFa
    删除后元素个数:3
    元组中的第一个元素更新为:cx
    a:cx  b:LiXiaoLong  c:100
    

    相关文章

      网友评论

        本文标题:Typescript了解

        本文链接:https://www.haomeiwen.com/subject/qypcfhtx.html