欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析如何使用JavaScript輕松實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換

 更新時(shí)間:2024年10月24日 09:14:42   作者:Hamm  
這篇文章主要為大家詳細(xì)介紹了如何使用JavaScript輕松實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

之前寫了一篇 《TypeScript裝飾器之我們是這么處理項(xiàng)目數(shù)據(jù)轉(zhuǎn)換的》,有很多朋友私信和評(píng)論說,如果沒有 TypeScript裝飾器,純 JavaScript 有沒有什么好的數(shù)據(jù)轉(zhuǎn)換的方案呢?

很遺憾,還真有,雖然沒有 TypeScript 那么優(yōu)雅,但是也足夠好用。

這里用到了 Getter/Setter,以及 Object 原型鏈相關(guān)的知識(shí)。

一、假設(shè)需求

1. 后端返回的數(shù)據(jù)

這里我們先假設(shè)從后端來(lái)了個(gè) JSON 長(zhǎng)這樣:

{
  id: 1,
  nickname: 'Hamm',
  age: 18,
  sex: 1,
  createTime: 1707021296000,
  bio: '一些廢話,前端不需要的字段'
}

其中,id createTime 是固定返回的公共屬性。

2. 前端類型聲明

基類

class BaseEntity {
  id;
  createTime;
}

用戶類

class User extends BaseEntity {
  nickname;
  age;
  sex;
}

3. 轉(zhuǎn)換要求

轉(zhuǎn)換到類時(shí)

  • createTime 轉(zhuǎn)為 Date類型;
  • 前端使用 gender 作為性別字段,且需要根據(jù) 1/0 顯示男女;
  • 前端沒有 bio 字段,需要過濾掉。

轉(zhuǎn)換到 JSON 時(shí)

  • createTime 轉(zhuǎn)回后端需要的時(shí)間戳
  • gender 還原回后段需要的 sex,并且轉(zhuǎn)換為 1/0

二、實(shí)現(xiàn)思路

正如我們之前有篇關(guān)于 幾個(gè)有關(guān)Getter/Setter的小故事 文章中提到,我們可以用 getter/setter 來(lái)攔截?cái)?shù)據(jù)達(dá)到轉(zhuǎn)換數(shù)據(jù)的目的:

1. 基于基類實(shí)現(xiàn) fromJson 靜態(tài)方法

class BaseEntity {
  id;
  createTime;

  static fromJson(json) {
    const user = new this();
    const filteredJson = Object.keys(json).reduce((item, key) => {
      if (user.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      if (user.__proto__.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      return item;
    }, {});
    const entity = Object.assign(user, filteredJson);
    if (entity.createTime) {
      entity.createTime = new Date(entity.createTime);
    }
    return entity;
  }
}

class UserEntity extends BaseEntity {
  nickname;
  age;
  gender;
  get sex() {
    return this.gender;
  }
  set sex(value) {
    if (value === undefined || value === null) {
      this.gender = undefined
    }else{
      this.gender = value === 1 ? '男' : '女';
    }
  }
}

const json = {
  id: 1,
  nickname: 'Hamm',
  age: 18,
  sex: 1,
  createTime: 1707021296000,
  bio: '一些廢話,前端不需要的字段'
}
console.log("json", json)
const user = UserEntity.fromJson(json)
console.log("entity", user)

其中,我們通過讀取 getter/setter 以及本身的屬性,來(lái)確定哪些是直接賦值,哪些是走set方法,哪些不存在的需要忽略。

2.調(diào)試輸出,美滋滋

json {
  id: 1,
  nickname: 'Hamm',
  age: 18,
  sex: 1,
  createTime: 1707021296000,
  bio: '一些廢話,前端不需要的字段'
}
entity UserEntity {
  id: 1,
  createTime: 2024-02-04T04:34:56.000Z,
  nickname: 'Hamm',
  age: 18,
  gender: '男'
}

3. 實(shí)現(xiàn)動(dòng)態(tài)方法的 toJson

接下來(lái),我們需要將 BaseEntity 添加一個(gè) toJson 方法,用于將實(shí)體轉(zhuǎn)換為 JSON 格式,且給 UserEntitysex getter 做一下數(shù)據(jù)轉(zhuǎn)換:

class BaseEntity {
  id;
  createTime;

  static fromJson(json) {
    const user = new this();
    const filteredJson = Object.keys(json).reduce((item, key) => {
      if (user.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      if (user.__proto__.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      return item;
    }, {});
    const entity = Object.assign(user, filteredJson);
    if (entity.createTime) {
      entity.createTime = new Date(entity.createTime);
    }
    return entity;
  }

  toJson() {
    const proto = Object.getPrototypeOf(this);
    const ownProperties = Object.getOwnPropertyNames(this);
    const getters = Object.getOwnPropertyNames(proto).filter(key => {
      const descriptor = Object.getOwnPropertyDescriptor(proto, key);
      return descriptor && typeof descriptor.get === 'function';
    });
    const json = {}
    getters.forEach(key => {
      if (this.__proto__.hasOwnProperty(key)) {
        json[key] = this[key]
        this[key] = undefined
      }
    })
    ownProperties.forEach(key => {
      if (this.hasOwnProperty(key)) {
        json[key] = this[key]
        this[key] = undefined
      }
    })
    if (json.createTime && typeof json.createTime === 'object') {
      json.createTime = json.createTime.valueOf()
    } else {
      json.createTime = undefined
    }
    return JSON.parse(JSON.stringify(json))
  }
}

class UserEntity extends BaseEntity {
  nickname;
  age;
  gender;
  get sex() {
    if (this.gender === undefined || this.gender === null) {
      return undefined
    }
    return this.gender === '男' ? 1 : 0;
  }
  set sex(value) {
    if (value === undefined || value === null) {
      this.gender = undefined
    }else{
      this.gender = value === 1 ? '男' : '女';
    }
  }
}

const user = new UserEntity()
user.id = 1
user.nickname = "Hamm"
user.age = 18
user.gender = "男"
user.createTime = new Date()
console.log("entity", user)
console.log("json", user.toJson())

4. 繼續(xù)調(diào)試輸出,繼續(xù)美滋滋

entity UserEntity {
  id: 1,
  createTime: 2024-10-23T19:37:07.521Z,
  nickname: 'Hamm',
  age: 18,
  gender: '男'
}
json { sex: 1, id: 1, createTime: 1729712227521, nickname: 'Hamm', age: 18 }

三、完整代碼如下

class BaseEntity {
  id;
  createTime;

  static fromJson(json) {
    const user = new this();
    const filteredJson = Object.keys(json).reduce((item, key) => {
      if (user.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      if (user.__proto__.hasOwnProperty(key)) {
        item[key] = json[key];
      }
      return item;
    }, {});
    const entity = Object.assign(user, filteredJson);
    if (entity.createTime) {
      entity.createTime = new Date(entity.createTime);
    }
    return entity;
  }

  toJson() {
    const proto = Object.getPrototypeOf(this);
    const ownProperties = Object.getOwnPropertyNames(this);
    const getters = Object.getOwnPropertyNames(proto).filter(key => {
      const descriptor = Object.getOwnPropertyDescriptor(proto, key);
      return descriptor && typeof descriptor.get === 'function';
    });
    const json = {}
    getters.forEach(key => {
      if (this.__proto__.hasOwnProperty(key)) {
        json[key] = this[key]
        this[key] = undefined
      }
    })
    ownProperties.forEach(key => {
      if (this.hasOwnProperty(key)) {
        json[key] = this[key]
        this[key] = undefined
      }
    })
    if (json.createTime && typeof json.createTime === 'object') {
      json.createTime = json.createTime.valueOf()
    } else {
      json.createTime = undefined
    }
    return JSON.parse(JSON.stringify(json))
  }
}

class UserEntity extends BaseEntity {
  nickname;
  age;
  gender;
  get sex() {
    if (this.gender === undefined || this.gender === null) {
      return undefined
    }
    return this.gender === '男' ? 1 : 0;
  }
  set sex(value) {
    if (value === undefined || value === null) {
      this.gender = undefined
    }else{
      this.gender = value === 1 ? '男' : '女';
    }
  }
}

const json = {
  id: 1,
  nickname: 'Hamm',
  age: 18,
  sex: 1,
  createTime: 1707021296000,
  bio: '一些廢話,前端不需要的字段'
}
console.log("json",json)
const user = UserEntity.fromJson(json)
console.log("entity", user)
console.log("json", user.toJson())

四、總結(jié)

如上代碼,我們利用了 getter/setter 以及 Object 原型鏈上的一些方法來(lái)完成了轉(zhuǎn)換。

雖然稍顯麻煩,但也算解決了不在外部寫一些方法來(lái)轉(zhuǎn)換。

各有所長(zhǎng),實(shí)現(xiàn)的方式有很多種,但思路才是很好玩的東西。

當(dāng)然,JavaScript的裝飾器提案已經(jīng)快發(fā)布了,后續(xù)我們將繼續(xù)摸索用裝飾器在JavaScript中實(shí)現(xiàn)類似功能。(TypeScript的裝飾器我們敢用,是因?yàn)榫幾g后的JS代碼沒有包含裝飾器的部分,在瀏覽器上不會(huì)有問題。)

到此這篇關(guān)于淺析如何使用JavaScript輕松實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)JavaScript數(shù)據(jù)轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js實(shí)現(xiàn)全選和全不選

    js實(shí)現(xiàn)全選和全不選

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)全選和全不選,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 利用純JS實(shí)現(xiàn)像素逐漸顯示的方法示例

    利用純JS實(shí)現(xiàn)像素逐漸顯示的方法示例

    這篇文章主要給大家介紹了利用純JS實(shí)現(xiàn)像素逐漸顯示的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • JavaScript tab選項(xiàng)卡插件實(shí)例代碼

    JavaScript tab選項(xiàng)卡插件實(shí)例代碼

    這篇文章主要介紹了JavaScript tab選項(xiàng)卡插件實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Echarts圖例組件的屬性與源代碼

    Echarts圖例組件的屬性與源代碼

    圖例組件展現(xiàn)了不同系列的標(biāo)記(symbol),顏色和名字,可以通過點(diǎn)擊圖例控制哪些系列不顯示,這篇文章主要給大家介紹了關(guān)于Echarts圖例組件的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • IE6瀏覽器中window.location.href無(wú)效的解決方法

    IE6瀏覽器中window.location.href無(wú)效的解決方法

    這篇文章主要介紹了IE6瀏覽器中window.location.href無(wú)效的解決方法,給出了正確與錯(cuò)誤的實(shí)例對(duì)比,分析跳轉(zhuǎn)無(wú)效的原因與解決方法,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-11-11
  • JavaScript利用canvas實(shí)現(xiàn)鼠標(biāo)跟隨特效

    JavaScript利用canvas實(shí)現(xiàn)鼠標(biāo)跟隨特效

    canvas是一個(gè)很神奇的玩意兒,比如畫表格、畫海報(bào)圖都要用canvas去做。本文就來(lái)利用canvas制作個(gè)簡(jiǎn)單的鼠標(biāo)跟隨特效,快跟隨小編一起學(xué)習(xí)一下吧
    2022-10-10
  • JavaScript中三種for循環(huán)語(yǔ)句的使用總結(jié)(for、for...in、for...of)

    JavaScript中三種for循環(huán)語(yǔ)句的使用總結(jié)(for、for...in、for...of)

    這篇文章主要給大家介紹了關(guān)于JavaScript中三種for循環(huán)語(yǔ)句的使用的相關(guān)資料,For循環(huán)用在需要重復(fù)執(zhí)行的某些代碼,本文介紹的三種for循環(huán)分別包括for、for...in、for...of,需要的朋友可以參考下
    2021-06-06
  • JS實(shí)現(xiàn)面包屑導(dǎo)航功能從零開始示例

    JS實(shí)現(xiàn)面包屑導(dǎo)航功能從零開始示例

    這篇文章主要為大家介紹了JS實(shí)現(xiàn)面包屑導(dǎo)航功能從零開始示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • reveal.js PPT制作框架使用教程

    reveal.js PPT制作框架使用教程

    reveal.js是一款開源的HTML演示框架,由Hakim El Hattab開發(fā),遵循MIT許可證,它支持嵌套幻燈片、Markdown、自動(dòng)動(dòng)畫、PDF導(dǎo)出等多種功能,本文就來(lái)介紹一下如何使用,感興趣的可以了解一下
    2024-09-09
  • 使用JavaScript將圖片合并為PDF的實(shí)現(xiàn)

    使用JavaScript將圖片合并為PDF的實(shí)現(xiàn)

    在日常工作中,我們可能需要拍攝一些照片并將圖像合并到PDF文件中,這可以通過許多應(yīng)用來(lái)完成,Dynamsoft Document Viewer讓這一操作更加方便,在本文中,我們將使用Dynamsoft Document Viewer創(chuàng)建一個(gè)Web應(yīng)用,用JavaScript將圖像合并到PDF中,需要的朋友可以參考下
    2024-07-07

最新評(píng)論