TypeScript 註解(下)

引言

繼上週的文章《TypeScript 註解(上)》,補充在最後未實現的屬性註解。

本文可能需要紮實的JavaScript功底,我儘量給大家通俗地講解。

實現

建立新項目

上週的項目建立的太不正規了,直接建個文件夾,然後寫的TS代碼,太過不規範。

這次我們使用npm init初始化一個新的前臺項目。

clipboard.png

創建成功後,項目中就出現了我們熟知的package.json文件。

clipboard.png

安裝依賴

本次,我們需要使用反射實現一些高級的功能。

反射是指計算機程序在運行時可以訪問、檢測和修改它本身狀態或行爲的一種能力。

根據官方文檔的環境要求,使用TypeScript反射,我們需要先安裝reflect-metadata包。

npm i reflect-metadata --save

屬性註解

屬性註解在屬性上聲明,屬性註解的表達式在運行期間像函數一樣被調用,並帶着以下兩個參數:

  1. 如果是在靜態成員上,則是類的構造函數;如是在實例成員上,則是類的原型。
  2. 成員的名稱。

所以,一個標準的屬性註解如下所示:返回一個帶有兩個參數的閉包。

function annotation(target: string) {
    return function(target, propertyKey) {
    }
}

看下面的實例代碼:這裏直接返回Reflect.metadata代替原閉包,因爲metadata方法的返回值,就符合該規範。

clipboard.png

import "reflect-metadata";

// 聲明唯一的元數據key
const formatMetaDataKey = Symbol("format");

// 前綴註解
function prefix(target: string) {
    // 根據key將前綴存至元數據中
    return Reflect.metadata(formatMetaDataKey, target);
}

class Person {

    constructor(message: string) {
        this.message = message;
    }

    @prefix("hello, ")
    message: string;

    speak(): void {
        // 獲取元數據前綴,key,當前對象,message屬性
        const prefix = Reflect.getMetadata(formatMetaDataKey, this, "message");
        console.log(prefix + this.message);
    }
}

const person = new Person("world");
person.speak();

通過在字符串屬性上聲明的prefix註解,來添加該字符串應該顯示的前綴。

clipboard.png

功能很簡單,也就不再贅述了。以後想寫類似功能時照葫蘆畫瓢就是了,這裏主要是對一些比較繁瑣的代碼加以研究。

Symbol

大家想必注意到了這裏的Symbol了,這是個什麼東西呢?

// 聲明唯一的元數據key
const formatMetaDataKey = Symbol("format");

Symbol是一種新的基本數據類型。

Google搜索JavaScript數據類型,發現谷歌的第一條已然過時,面試也常考,這裏糾正一下。

clipboard.png

JavaScript共有7種數據類型,重點!!!

6種基本數據類型:

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (ECMAScript 6 新定義)

Object

例子

說來說去,Symbol到底是個啥玩意?一個例子帶你看明白。

let obj = {
    id: 1
};

obj['id'] = 2;
// 覆蓋了原id
console.log(obj);

const id = Symbol('id');
obj[id] = 3;
// 添加Symbol key的屬性
console.log(obj);

const id2 = Symbol('id');
obj[id2] = 6;
// 不覆蓋原Symbol key
console.log(obj);

clipboard.png

對象中允許字符串或Symbol作爲key,從這個例子我們可以看出,字符串的key不具有唯一性,而Symbolkey能保證唯一,不進行覆蓋。

Token

這個唯一性覆蓋問題就像之前在網上送檢項目中遇到的問題,因爲項目已停工,也就沒有和大家提。這裏和大家簡單說一下。

使用的全局配置是使用字符串注入的,因爲是一個容器,假設我們的框架中也用到了'CONFIG'的字符串注入,那我們加入的配置就會覆蓋原框架配置,給框架注入了錯誤的對象,然後就出現了錯誤但是就是找不着原因的一系列問題。

providers: [
    { provide: 'CONFIG', useValue: YUNZHI_GLOBAL_CONFIG }
]

class TestComponent {
    constructor(@Inject('CONFIG') private config) {
    }
}

其實Angular已經解決,以後不要再通過字符串注入,推薦通過InjectionToken注入。

const CONFIG_TOKEN = new InjectionToken<VALUE_TYPE>('CONFIG');

總結

初級程序員的業餘生活,學習,學習,學習。

clipboard.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章