<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      hackftz

      bits change world

      導航

      深入理解TypeScript——文檔篇之類

      Posted on 2020-10-01 19:41  hackftz  閱讀(109)  評論(0)    收藏  舉報

      一、js和ts類的區別

             js是基于類的面向對象方式,構建父子類的繼承結構,寫起來不簡潔,也不形象。ts則是以簡潔明了的方式實現類的定義、繼承、擴展等等。

            之前我也提過,js最終會登錄瀏覽器平臺,但是至少不是現在,所以在下一個js時代之前,我們需要定ts來規范當前的客戶端代碼。

      二、用ts實現類

      class Greeter {
          greeting: string;
          constructor(message: string) {
              this.greeting = message;
          }
          greet() {
              return "Hello, " + this.greeting;
          }
      }
      
      let greeter = new Greeter("world");
      

      三、繼承

             使用extends 關鍵字來繼承。

      class Animal { // Animal是基類,也叫超類
          move(distanceInMeters: number = 0) {
              console.log(`Animal moved ${distanceInMeters}m.`);
          }
      }
      
      class Dog extends Animal { // Dog是派生自Animal的派生類,也叫子類
          bark() {
              console.log('Woof! Woof!');
          }
      }
      
      const dog = new Dog();
      dog.bark();
      dog.move(10);
      

             派生類的構造函數必須包含 "super" 調用。這是ts強制執行的一條重要規則。

      // 如果父類下沒有構造函數,如下
      class Animal {
        move(distanceInMeters: number = 0) {
      
        }
      }
      
      class Snake extends Animal {
        constructor(name: string) {
          super() // 如果父類沒有定義構造函數,父類會有默認值,什么都不做,但是子類必須要在構造函數中調用super
        }
        move(distanceInMeters = 5) {
            console.log("Slithering...");
            super.move(distanceInMeters);
        }
      }
      
      let sam = new Snake("Sammy the Python");
      
      console.log(sam);
      
      // 父類含有構造函數
      class Animal {
          name: string;
          constructor(theName: string) { // 在子類中執行基類的構造函數
              this.name = theName; 
          }
          move(distanceInMeters: number = 0) {
              console.log(`${this.name} moved ${distanceInMeters}m.`);
          }
      }
      
      class Snake extends Animal {
          constructor(name: string) { super(name); }
          move(distanceInMeters = 5) {
              console.log("Slithering...");
              super.move(distanceInMeters);
          }
      }
      
      let sam = new Snake("Sammy the Python");
      sam.move();
      

      四、公共、私有與受保護的修飾符

      public

             前置定義,ts里可以不寫即為默認為public,可以自由的訪問定義的值。

      private

             不能再聲明它的類的外部被訪問。即為私有屬性。

      protected

             protected修飾符與 private修飾符的行為很相似,但有一點不同, protected成員在派生類中仍然可以訪問,但是注意:依然不能在類的外面被訪問。

      class Person {
          protected name: string;
          constructor(name: string) { this.name = name; }
      }
      
      class Employee extends Person {
          private department: string;
      
          constructor(name: string, department: string) {
              super(name)
              this.department = department;
          }
      
          public getElevatorPitch() {
              return `Hello, my name is ${this.name} and I work in ${this.department}.`;
          }
      }
      
      let howard = new Employee("Howard", "Sales");
      console.log(howard.getElevatorPitch());
      console.log(howard.name); // 錯誤
      

             構造函數也可以被標記成 protected。 這意味著這個類不能在包含它的類外被實例化,但是能被繼承。

      // 類屬性 name、constructor => protected
      class Person {
          protected name: string;
          protected constructor(theName: string) { this.name = theName; }
      }
      
      // Employee 能夠繼承 Person
      class Employee extends Person {
          private department: string;
      
          constructor(name: string, department: string) {
              super(name);
              this.department = department;
          }
      
          public getElevatorPitch() {
              return `Hello, my name is ${this.name} and I work in ${this.department}.`;
          }
      }
      
      let howard = new Employee("Howard", "Sales");
      let john = new Person("John"); // 類“Person”的構造函數是受保護的,僅可在類聲明中訪問。
      
      // 類屬性 name => not protected, constructor => protected
      class Person {
        protected name: string;
        constructor(theName: string) { this.name = theName; }
      }
      
      // Employee 能夠繼承 Person
      class Employee extends Person {
        private department: string;
      
        constructor(name: string, department: string) {
            super(name);
            this.department = department;
        }
      
        public getElevatorPitch() {
            return `Hello, my name is ${this.name} and I work in ${this.department}.`;
        }
      }
      
      let howard = new Employee("Howard", "Sales");
      let john = new Person("John");
      console.log(john.name); // 屬性“name”受保護,只能在類“Person”及其子類中訪問。ts(2445)
      

      五、readonly修飾符

             使用 readonly關鍵字將屬性設置為只讀的。 只讀屬性必須在聲明時或構造函數里被初始化。

      class Octopus {
          readonly name: string;
          readonly numberOfLegs: number = 8;
          constructor (theName: string) {
              this.name = theName;
          }
      }
      let dad = new Octopus("Man with the 8 strong legs");
      dad.name = "Man with the 3-piece suit"; // 錯誤! name 是只讀的.
      

             參數屬性:參數屬性可以方便地讓我們在一個地方定義并初始化一個成員。

      class Octopus {
          readonly numberOfLegs: number = 8;
          constructor(readonly name: string) { // 聲明并初始化一個私有成員
          }
      }
      
      // 等價于
      class Octopus {
          readonly name: string;
          readonly numberOfLegs: number = 8;
          constructor (theName: string) {
              this.name = theName;
          }
      }
      

      六、存取器

      let 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 {
                  console.log("Error: Unauthorized update of employee!");
              }
          }
      }
      
      let employee = new Employee();
      
      console.log(employee.fullName); // Property '_fullName' has no initializer and is not definitely assigned in the constructor.  
      
      employee.fullName = "Bob Smith";
      
      if (employee.fullName) {
          console.log(employee.fullName);
      }
      

      注意:

      • 存取器要求你將編譯器設置為輸出ECMAScript 5或更高。 不支持降級到ECMAScript 3。
      • 其次,只帶有 get不帶有 set的存取器自動被推斷為 readonly

      七、靜態屬性

             這些屬性存在于類本身上面而不是類的實例上。

      class Grid {
          static origin = {x: 0, y: 0};
          calculateDistanceFromOrigin(point: {x: number; y: number;}) {
              let xDist = (point.x - Grid.origin.x); // 如同在實例屬性上使用 this.前綴來訪問屬性一樣,這里我們使用 Grid.來訪問靜態屬性。
              let yDist = (point.y - Grid.origin.y);
              return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
          }
          constructor (public scale: number) { }
      }
      

      八、抽象類

             抽象類做為其它派生類的基類使用。 它們一般不會直接被實例化。

             不同于接口,抽象類可以包含成員的實現細節。 abstract關鍵字是用于定義抽象類和在抽象類內部定義抽象方法。

      abstract class Animal {
          abstract makeSound(): void;
          move(): void {
              console.log('roaming the earch...');
          }
      }
      

             抽象類中的抽象方法不包含具體實現并且必須在派生類中實現。 抽象方法的語法與接口方法相似。 兩者都是定義方法簽名但不包含方法體。 然而,抽象方法必須包含 abstract關鍵字并且可以包含訪問修飾符。

      abstract class Department {
      
        constructor(public name: string, age: number = 10) { // 如果age這里不用public定義,則它是一個局部變量,不能從實例的this.上獲取到
        }
      
        printName(): void {
            console.log('Department name: ' + this.name);
        }
      
        abstract printMeeting(): void; // 必須在派生類中實現
      }
      
      class AccountingDepartment extends Department {
      
        constructor() {
            super('Accounting and Auditing'); // 在派生類的構造函數中必須調用 super()
        }
      
        printMeeting(): void {
            console.log('The Accounting Department meets each Monday at 10am.');
        }
      
        generateReports(): void {
            console.log('Generating accounting reports...');
        }
      }
      
      let department: Department; // 允許創建一個對抽象類型的引用
      // department = new Department(); // 錯誤: 不能創建一個抽象類的實例
      department = new AccountingDepartment(); // 允許對一個抽象子類進行實例化和賦值
      console.log(department.name); // Accounting and Auditing
      console.log(department.age); // 類型“Department”上不存在屬性“age”。
      department.printName();
      department.printMeeting();
      // department.generateReports(); // 錯誤: 方法在聲明的抽象類中不存在
      

             注意上面標記*處: Typescript 提供的簡寫形式 — 用構造函數的參數直接定義屬性。

      九、高級技巧

      1. 構造函數

        class Greeter {
            static standardGreeting = "Hello, there";
            greeting: string;
            greet() {
                if (this.greeting) {
                    return "Hello, " + this.greeting;
                }
                else {
                    return Greeter.standardGreeting;
                }
            }
        }
        
        let greeter1: Greeter;
        greeter1 = new Greeter();
        console.log(greeter1.greet());
        
        let greeterMaker: typeof Greeter = Greeter; // Greeter類的類型,而不是實例的類型。
        greeterMaker.standardGreeting = "Hey there!";
        
        let greeter2: Greeter = new greeterMaker();
        console.log(greeter2.greet());
        
      2. 把類當作接口

        因為類可以創建出類型,所以你能夠在允許使用接口的地方使用類。

        簡而言之,就是把類當成接口來用。

        class Point {
            x: number;
            y: number;
        }
        
        interface Point3d extends Point {
            z: number;
        }
        
        let point3d: Point3d = {x: 1, y: 2, z: 3};
        
      主站蜘蛛池模板: 国产a在视频线精品视频下载| 亚洲国产成人不卡高清麻豆| 国产精品国产三级国产专| 久久天天躁夜夜躁狠狠| 陆良县| 国产精品一区在线蜜臀| 精品国偷自产在线视频99| 亚洲国产大胸一区二区三区| 国产性生大片免费观看性| 日韩精品中文字幕人妻| 日韩中文字幕有码午夜美女| 妖精视频yjsp毛片永久| 在线 欧美 中文 亚洲 精品| 91精品国产老熟女在线| 色伦专区97中文字幕| 国产精品白丝久久AV网站| 成人午夜激情在线观看| 欧美牲交a欧美在线| 国产美女被遭强高潮免费一视频| 少妇午夜啪爽嗷嗷叫视频| 亚洲色一色噜一噜噜噜| 极品人妻少妇一区二区三区| 久久99国产精一区二区三区!| 国产性色av免费观看| 国产电影一区二区三区| 亚洲熟女乱综合一区二区| 丰满爆乳一区二区三区| 固始县| 国产极品粉嫩学生一线天| 亚洲精品麻豆一区二区| 97欧美精品系列一区二区| 国产熟睡乱子伦视频在线播放| 久久精品国产亚洲不av麻豆| 久久精品色一情一乱一伦| 亚洲乱妇老熟女爽到高潮的片| 日韩人妻av一区二区三区| 亚洲欧美日韩综合久久久| 偷拍专区一区二区三区| 精品一区二区久久久久久久网站 | 日韩永久永久永久黄色大片| 亚洲精品国产自在现线最新|