bunny筆記|TS基礎(chǔ)(3):給類定義屬性草则、構(gòu)造函數(shù)、Getters/Setters蟹漓、基類和派生類初始化的順序炕横、繼承內(nèi)置類型、泛型類葡粒、類型守衛(wèi)等

01

給類定義屬性

class Point {
    // x: number = 2
    // y: number = 4

    x: number
    y: number
    constructor() {
        this.x = 2222
        this.y = 22255
    }
}

const pt = new Point()
pt.x = 33
pt.y = 22

//也可以斷言

class OKG{
    name!:string
}

02

class Greater {
    readonly name: string = 'world'
    constructor() {
        this.name = 'hello'
    }
}

const G = new Greater()
//G.name = 'g' //報(bào)錯(cuò)份殿,無法分配到name膜钓,因?yàn)樗侵蛔x屬性

//constructor() 是再new的時(shí)候運(yùn)行的,可以傳入?yún)?shù),定義參數(shù)類型等

class Greater2 {
    readonly name: string = 'world'
    constructor(other?: string) {
        if (other !== undefined) {
            this.name = other
        }

    }
}

const g = new Greater2('hello')
console.log(g.name);


03

構(gòu)造函數(shù)-constructor卿嘲∷绦保可以定義參數(shù),傳初始值拾枣,然后再重新賦值即可

class P {
    x: string;
    z: number
    constructor(x: string='', z: number=0) {
        this.x = x;
        this.z = z
    }
}
const t = new P()
console.log(t.z);
console.log(t.x);


//注意:構(gòu)造函數(shù)不能有類型參數(shù)沃疮,構(gòu)造函數(shù)不能有返回類型注釋

04

類里面的函數(shù),我們稱之為方法


class Int {
    x: number;
    z: number
    constructor(x: number = 2, z: number = 0) {
        this.x = x;
        this.z = z
    }

    add(sum: number) {
        let y = this.z + this.x
        let su = sum + y
        console.log(y);
        console.log(su);
    }
}

const pg = new Int()
pg.x = 4
pg.z = 5
pg.add(3)//傳實(shí)參

05

Getters/Setters
如果存在get,但沒有set屬性梅肤,則改屬性自動(dòng)是可讀的
如果沒有指定setter參數(shù)的類型司蔬,它將從getter返回類型中推斷出來
//訪問器和設(shè)置器必須有相同的成員可見性 get和set的函數(shù)方法名相同

class C {
    _length = 9;

    get length() {
        return this._length;
    }

    set length(value) {
        this._length = value
    }
}

const cl = new C()
console.log(cl.length);// 9

06

class MyClass {
    [s: string]: boolean | ((s: string) => boolean)
    x = true

    check(s: string) {
        return this[s] as boolean //斷言
    }
}

07


interface Pingable {
    ping(): void;
}

class SO implements Pingable {
    ping(): void {
        console.log("ping!");

    }
}

let so: SO = new SO()
so.ping()

interface A{
    x:number;
    y?:number
}

class C2 implements A{
    x=99
}

const cll=new C2()
console.log(cll.x);//99
//console.log(cll.y);//undefined,C2上不存在屬性y

08

class Animal {
    dog: string
    constructor(dog: string = '') {
        this.dog = dog
    }
}

class Dog extends Animal {
    pick: string
    constructor(pick: string = '') {
        super()
        this.pick = pick
    }
}

const zoo = new Dog()
console.log(zoo.dog = 'yellow');
console.log(zoo.pick = 'pink');

09

重寫方法(基類和派生類)

//基類
class Base {
    greet() {
        console.log('hello lady');

    }
}

//派生類
class Derived extends Base {
    greet(name?: string): void {
        if (name === undefined) {
            super.greet()
        } else {
            console.log(name.toUpperCase());//toUpperCase()將傳入的string轉(zhuǎn)換為大寫
        }
    }
}

const d = new Derived()
d.greet()
d.greet('reader')

//注意:派生類要遵循基類的契約,契約就是凭语,如Derived類覆蓋Base類葱她,一定要與Base兼容,比如這里傳入的參數(shù)似扔,如果name為必傳參數(shù)那么就會(huì)報(bào)錯(cuò)吨些,類型不匹配

const b:Base =d
b.greet()

10

基類和派生類初始化的順序
1.基類的字段被初始化
2.基類構(gòu)造函數(shù)運(yùn)行
3.派生類的字段被初始化
4.派生類構(gòu)造函數(shù)運(yùn)行

class Basic {
    name = "base";
    constructor() {
        console.log("my name is" + " " + this.name);


    }
}

class Deri extends Basic {
    name = "derived";
}

const dd = new Deri();

//優(yōu)先初始化 基類的初始值


11

繼承內(nèi)置類型,什么是內(nèi)置類型呢炒辉?比如array豪墅,error,map等等黔寇,這些TS內(nèi)置的一些對(duì)象.

//例:

class MsgError extends Error{

    constructor(m:string){
        super(m)

        // //es5及以下偶器,可以明確地設(shè)置原型
        // Object.setPrototypeOf(this,MsgError.prototype)

    } 
    sayHello(){
        return 'hello ' + this.message
    }
}

const msgError=new MsgError('lady')
console.log(msgError.sayHello()); //hello  lady


//這里的定義了一個(gè)類叫MsgError,它繼承了Error這個(gè)內(nèi)置的對(duì)象,Error就是內(nèi)置的一個(gè)類或者一個(gè)對(duì)象缝裤,有時(shí)候我們?cè)诜治鰞?nèi)置類型的結(jié)構(gòu)的時(shí)候屏轰,可能出乎我們的意料,這個(gè)呢憋飞,主要表現(xiàn)在我們編譯的時(shí)候使用的是什么target霎苗,比如我們使用ES6以上的版本,我們可能不用關(guān)心太多的關(guān)于繼承內(nèi)置類型的一些問題榛做,如果是ES5及以下的版本的話唁盏,就需要注意了

12

class A{
    constructor(){

    }

    public add(){

    }

    protected pro(){

    }

    private pri(){

    }
}

const a:A=new A()
a.add()

13

類里的static區(qū)塊

static 靜態(tài)成員和static # 靜態(tài)的區(qū)別,最大的區(qū)別是:帶#號(hào)的就變成了私有的這樣的屬性检眯,比如說我們可以在類的內(nèi)部通過getter來去訪問厘擂,但訪問的時(shí)候呢,我們?nèi)耘f是可以通過類名去訪問它锰瘸,同時(shí)我們?cè)陬惱镞€可以寫一個(gè)static這樣的塊刽严,這個(gè)static后面可以直接跟這個(gè)大括號(hào){},然后我們可以通過類名訪問我們當(dāng)前類里邊的通過#號(hào)來定義的這些靜態(tài)的屬性获茬,那我們?cè)陬惖耐膺呍噲D去訪問一下這個(gè)#count 是行不通的港庄,也就是說它是私有的



class Foo {
    static #count = 0;

    get count() {
        return Foo.#count;
    }

    static {
        try {
            const lastInstances = {
                length: 100
            }
            Foo.#count += lastInstances.length;
        }
        catch{
            //....
        }
    }
}

// Foo.#count //報(bào)錯(cuò)倔既,屬性#count在類FOO外部不可訪問,因?yàn)樗哂袑S脴?biāo)識(shí)符

14

泛型類

class Box<Type>{
    contents:Type
    constructor(value:Type){
        this.contents=value
    }
   // static defaultValue:Type//報(bào)錯(cuò):靜態(tài)成員不能引用類類型參數(shù)
}

const box:Box<string>=new Box('bunny')

15

類運(yùn)行時(shí)的this

class Myclass {
    name = "Myclass";
    // getName() {
    //     return this.name
    // }

    // //(1)箭頭函數(shù)
    // getName=()=> {
    //     return this.name
    // }

    //(2)this參數(shù)
        getName(this:Myclass) {
        return this.name
    }
}

const c = new Myclass()
console.log(c.getName());//Myclass
const obj = {
    name: "obj",
    getName: c.getName
}

// console.log(obj.getName()); //obj

//得到的name是const下的name鹏氧,而不是我們初始化指向this下的name渤涌。解決方法:(1)箭頭函數(shù)。(2)this參數(shù)

//(1)使用箭頭函數(shù)后得到的是Myclass
//console.log(obj.getName()); //Myclass
//(2)使用this參數(shù)后得到的是obj .就是說把还,誰調(diào)的我我就打印誰
console.log(obj.getName()); //obj

總結(jié):
為了保證我們類里邊的某個(gè)函數(shù)的this指向实蓬,沒有問題,我們可以采用箭頭函數(shù)和this參數(shù)兩種方法吊履,使用的時(shí)候一定要權(quán)衡安皱,this這個(gè)值保證在運(yùn)行的時(shí)候是正確的,即使我們沒有經(jīng)過TS檢查代碼也是如此艇炎。第二呢酌伊,使用箭頭函數(shù),它會(huì)使用更多的內(nèi)存缀踪,因?yàn)槊總€(gè)類實(shí)例將有它自己的副本每個(gè)函數(shù)都是這樣定義的居砖,第三個(gè)呢,使用箭頭函數(shù)不能在派生類中使用super.getName驴娃,也就是我們不能在子類里邊通過super來調(diào)父類這個(gè)方法了奏候,因?yàn)樵谠玩溨袥]有入口可以獲得基類的方法,那如果是我們使用this參數(shù)這種方式來解決這個(gè)問題唇敞,它也有一些取舍的地方蔗草,首先呢,javascripe調(diào)用者仍然可能在不知不覺的錯(cuò)誤中來用類的方法疆柔,比方說剛才我們最后的這個(gè)調(diào)用咒精,另外呢,每個(gè)類只有一個(gè)函數(shù)被分配旷档,而不是每個(gè)實(shí)例會(huì)創(chuàng)建一個(gè)函數(shù)狠轻,另外呢,基類方法這個(gè)定義仍然可以通過super來調(diào)用彬犯,這個(gè)要優(yōu)于剛才我們說的箭頭函數(shù),所以采用哪種方法取決于我們正常的業(yè)務(wù)需求即可

16

class Boxes {
    contents: string = "";
    set(value: string) {
        this.contents = value
       // console.log(this);//Boxes { contents: 'hello' }
        return this;
    }
}

class ClearableBoxes extends Boxes {
    clear() {
        this.contents = ''
    }
}
const boxes = new Boxes()
const bo = boxes.set('bunny')
console.log(bo);//此時(shí)this返回的是 Boxes { contents: 'bunny' }
// boxes.set('hello')

const boxes1 = new ClearableBoxes()
const bo1 = boxes1.set('bunny')
console.log(bo1);//此時(shí)this返回的是 ClearableBoxes { contents: 'bunny' }

17

//基于類型守衛(wèi)的this
//this is Type

class ValueBox<T>{
    value?: T

    hasValue(): this is { value: T } {
        return this.value !== undefined
    }
}

const valueBox = new ValueBox()
valueBox.value = 'bunny'

if (valueBox.hasValue()) {
    console.log(valueBox.value);//bunny 
}

18

class Params {
    constructor(public readonly x: number = 9, y: number = 99, private a: string = 'bunny') {
        //...
    }
}

const p = new Params()

//類表達(dá)式

const someClass = class <Type>{
    content: Type
    constructor(value: Type) {
        this.content = value
    }
}
const m = new someClass('bunny')
console.log(m.content)

19

abstract class AbstractBase{
    abstract getName():string

    printName(){
        console.log(this.getName());
        
    }
}

//const abst=new AbstractBase()//報(bào)錯(cuò)查吊,無法創(chuàng)建抽象類的實(shí)例

//想要調(diào)用抽象類的函數(shù)要再聲明一個(gè)類來繼承抽象類
class ExtAbstract extends AbstractBase{
    getName(): string {
         return 'bunny'
    }
}

const abstract=new ExtAbstract()
abstract.getName()
abstract.printName()

20

class Xx {
    x: number = 2
    y: number = 3
}
class Yy {
    x: number = 24
    y: number = 34
}

const xy: Xx = new Yy()
let x1 = xy.x = 88
console.log(x1);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谐区,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逻卖,更是在濱河造成了極大的恐慌宋列,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件评也,死亡現(xiàn)場(chǎng)離奇詭異炼杖,居然都是意外死亡灭返,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門坤邪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熙含,“玉大人,你說我怎么就攤上這事艇纺≡蹙玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵黔衡,是天一觀的道長(zhǎng)蚓聘。 經(jīng)常有香客問我,道長(zhǎng)盟劫,這世上最難降的妖魔是什么夜牡? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮侣签,結(jié)果婚禮上塘装,老公的妹妹穿的比我還像新娘。我一直安慰自己硝岗,他們只是感情好氢哮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著型檀,像睡著了一般冗尤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胀溺,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天裂七,我揣著相機(jī)與錄音,去河邊找鬼仓坞。 笑死背零,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的无埃。 我是一名探鬼主播徙瓶,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嫉称!你這毒婦竟也來了侦镇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤织阅,失蹤者是張志新(化名)和其女友劉穎壳繁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闹炉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蒿赢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渣触。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡羡棵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出昵观,到底是詐尸還是另有隱情晾腔,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布啊犬,位于F島的核電站灼擂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏觉至。R本人自食惡果不足惜剔应,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望语御。 院中可真熱鬧峻贮,春花似錦、人聲如沸应闯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碉纺。三九已至船万,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骨田,已是汗流浹背耿导。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留态贤,地道東北人舱呻。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悠汽,于是被迫代替她去往敵國(guó)和親箱吕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容