亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一問(wèn)了解JavaScript中的元數(shù)據(jù)

 更新時(shí)間:2023年04月14日 14:25:07   作者:Moment  
本文主要介紹了一問(wèn)了解JavaScript中的元數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在 ES6 的規(guī)范當(dāng)中,ES6 支持元編程,核心是因?yàn)樘峁┝藢?duì) Proxy 和 Reflect 對(duì)象的支持,簡(jiǎn)單來(lái)說(shuō)這個(gè) API 的作用就是可以實(shí)現(xiàn)對(duì)變量操作的函數(shù)化,也就是反射。

元數(shù)據(jù)

什么是元數(shù)據(jù)

元數(shù)據(jù)是指附加在對(duì)象、類(lèi)、方法、屬性、參數(shù)上的數(shù)據(jù),它可以用來(lái)幫助實(shí)現(xiàn)某種業(yè)務(wù)功能需要用到的數(shù)據(jù)。

元數(shù)據(jù)的使用

Reflect-metadata-ES7 的一個(gè)提案,它主要用來(lái)聲明的時(shí)候添加和讀取元數(shù)據(jù),Typescript1.5+ 的版本已經(jīng)支持它,你只需要:

npm i reflect-metadata --save

緊接著你要在 tsconfig.json 文件中添加以下配置:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

defineMetadata() 和 getMetadata()

該方法是一個(gè)函數(shù)重載,它既可以接收三個(gè)參數(shù),也可以是四個(gè)參數(shù),具體定義如下所示:

function defineMetadata(metadataKey: any, metadataValue: any, target: Object): void;

function defineMetadata(metadataKey: any, metadataValue: any, target: Object, propertyKey: string | symbol): void;

它們的參數(shù)分別是:

  • metadataKey: 用于存儲(chǔ)和檢索元數(shù)據(jù)的鍵;
  • metadataValue: 元數(shù)據(jù)的值;
  • target: 要在其上定義元數(shù)據(jù)的目標(biāo)對(duì)象;
  • propertyKey: 目標(biāo)對(duì)象上的屬性;

有存值的就有取值的,這個(gè)方法也是一個(gè)函數(shù)重載,它的具體定義如下所示:

function getMetadata(metadataKey: any, target: Object, propertyKey: string | symbol): any;

function getOwnMetadata(metadataKey: any, target: Object): any;

它的具體使用如下所示:

import "reflect-metadata";

const moment = { address: "廣州" };

Reflect.defineMetadata("method", "hi,叼毛,你上班是不是在摸魚(yú)", moment);
console.log(Reflect.getMetadata("method", moment)); // hi,叼毛,你上班是不是在摸魚(yú)

Reflect.defineMetadata("method", "hi,靚仔,買(mǎi)菜嗎", moment, moment.address);
console.log(Reflect.getMetadata("method", moment, moment.address)); // hi,靚仔,買(mǎi)菜嗎

metadata()

Reflect.metadata(...) 方法的可以用于類(lèi)或者類(lèi)屬性上,它的具體定義如下所示:

function metadata(
  metadataKey: any,
  metadataValue: any
): {
  (target: Function): void;
  (target: Object, propertyKey: string | symbol): void;
};

Reflect.metadata 當(dāng)作 Decorator 使用,當(dāng)修飾類(lèi)時(shí),在類(lèi)上添加元數(shù)據(jù),當(dāng)修飾類(lèi)屬性時(shí),在類(lèi)原型的屬性上添加元數(shù)據(jù):

import "reflect-metadata";

@Reflect.metadata("inClass", "哇哈哈哈哈")
class Test {
  @Reflect.metadata("inMethod", "我要喝喜之郎,我要當(dāng)太空人")
  public hello(): string {
    return "hello world";
  }
}

console.log(Reflect.getMetadata("inClass", Test)); // 哇哈哈哈哈
console.log(Reflect.getMetadata("inMethod", new Test(), "hello")); // 我要喝喜之郎,我要當(dāng)太空人

在這里可能會(huì)有人就好奇了,這里面的方法怎么和上面的不一樣啊,上面的是 defineMetadata(...),而這里直接用的 metadata(...),這是為什么呢?

答案是 defineMetadata(...) 它要確定你要是在哪里定義的元數(shù)據(jù),而后者是直接以裝飾器的方式調(diào)用,它已經(jīng)明確知道了你就是給這個(gè)類(lèi)來(lái)定義的元數(shù)據(jù)。

獲取類(lèi)型信息并賦值

我們可以通過(guò) Reflect.getMetadata 方法來(lái)獲取屬性類(lèi)型,并且對(duì)該屬性進(jìn)行賦值,如下操作所示:

import "reflect-metadata";

function Prop(): PropertyDecorator {
  return (target, key: string) => {
    const type = Reflect.getMetadata("design:type", target, key);
    console.log(`${key} type: ${type.name}`);
    target[key] = "moment";
  };
}

class SomeClass {
  @Prop()
  public nickname!: string;
}

console.log(new SomeClass().nickname); // moment

例如在 vue-property-decorator 中通過(guò)使用 Reflect.getMetadata API,Prop Decorator 能獲取屬性類(lèi)型傳至 Vue,簡(jiǎn)要代碼如下:

import { Vue, Component, PropSync } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @PropSync('name', { type: String }) syncedName!: string
}

這樣的寫(xiě)法就等同于以下代碼所示:

export default {
  props: {
    name: {
      type: String,
    },
  },
  computed: {
    syncedName: {
      get() {
        return this.name
      },
      set(value) {
        this.$emit('update:name', value)
      },
    },
  },
}

除了能獲取屬性類(lèi)型以外,通過(guò) Reflect.getMetadata("design:paramtypes", target, key) 和 Reflect.getMetadata("design:returntype", target, key) 可以分別獲取函數(shù)參數(shù)類(lèi)型和返回值類(lèi)型,具體代碼如下所示:

import "reflect-metadata";

function Func(): PropertyDecorator {
  return (target, key: string) => {
    console.log(Reflect.getMetadata("design:paramtypes", target, key)); // 函數(shù)參數(shù)類(lèi)型
    console.log(Reflect.getMetadata("design:returntype", target, key)); // 返回值類(lèi)型
  };
}

class SomeClass {
  @Func()
  moment(value: boolean): string {
    return " ";
  }
}

自定義 metadataKey

除了能獲取類(lèi)型信息外,常用與自定義 metadataKey,并在合適的實(shí)際獲取它的值,具體實(shí)例代碼如下所示:

import "reflect-metadata";

function classDecorator(): ClassDecorator {
  return (target) => {
    Reflect.defineMetadata("class", "類(lèi)裝飾器", target);
  };
}

function methodDecorator(): MethodDecorator {
  return (target, key, descriptor) => {
    Reflect.defineMetadata("method", "方法裝飾器", target, key);
  };
}

@classDecorator()
class SomeClass {
  @methodDecorator()
  someMethod() {}
}

console.log(Reflect.getMetadata("class", SomeClass)); // 類(lèi)裝飾器
console.log(Reflect.getMetadata("method", new SomeClass(), "someMethod")); // 方法裝飾器

參考文獻(xiàn)

總結(jié)

元數(shù)據(jù)的應(yīng)用場(chǎng)景很多,其中 NestJs 就是使用了大量的元數(shù)組實(shí)現(xiàn)了控制反轉(zhuǎn)和依賴(lài)注入,將會(huì)在下一篇文章中講到,本篇文章到此結(jié)束。

到此這篇關(guān)于一問(wèn)了解JavaScript中的元數(shù)據(jù)的文章就介紹到這了,更多相關(guān)JavaScript 元數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論