最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

一、假設(shè)需求

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

這里我們先假設(shè)從后端來了個 JSON 長這樣:

{
  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)換到類時

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

轉(zhuǎn)換到 JSON 時

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

二、實現(xiàn)思路

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

1. 基于基類實現(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 以及本身的屬性,來確定哪些是直接賦值,哪些是走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. 實現(xiàn)動態(tài)方法的 toJson

接下來,我們需要將 BaseEntity 添加一個 toJson 方法,用于將實體轉(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 原型鏈上的一些方法來完成了轉(zhuǎn)換。

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

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

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

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

相關(guān)文章

  • Boostrap中柵格布局的實現(xiàn)

    Boostrap中柵格布局的實現(xiàn)

    這篇文章主要為大家詳細解析了Boostrap 柵格布局,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2017-01-01
  • JavaScript(js)處理的HTML事件、鍵盤事件、鼠標事件簡單示例

    JavaScript(js)處理的HTML事件、鍵盤事件、鼠標事件簡單示例

    這篇文章主要介紹了JavaScript(js)處理的HTML事件、鍵盤事件、鼠標事件,結(jié)合實例形式分析了JavaScript針對HTML事件、鍵盤事件及鼠標事件的簡單處理方法,需要的朋友可以參考下
    2019-11-11
  • JS的拖拽屬性draggable詳解

    JS的拖拽屬性draggable詳解

    這篇文章主要介紹了JS的拖拽屬性draggable詳解,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • JavaScript 對象與數(shù)組操作大全

    JavaScript 對象與數(shù)組操作大全

    本文介紹了JavaScript中的對象和數(shù)組,包括它們的基本概念、創(chuàng)建方法、屬性操作、遍歷方法、增刪改操作以及常用方法,同時,還討論了原型和繼承、對象的拷貝和方法簡寫等高級技巧,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • js文件中引入另一個js文件的4種方法總結(jié)

    js文件中引入另一個js文件的4種方法總結(jié)

    JavaScript文件是一個文本類型的文件,在任何文本編輯器中都可以被打開和編輯,JavaScript文件的擴展名為js,這篇文章主要給大家介紹了關(guān)于js文件中引入另一個js文件的4種方法總結(jié),需要的朋友可以參考下
    2023-12-12
  • JS中正則表達式全局匹配模式 /g用法詳解

    JS中正則表達式全局匹配模式 /g用法詳解

    本文章通過實例代碼給大家詳細介紹js中正則表達式的全局匹配模式 /g的用法,需要的朋友參考下
    2017-04-04
  • js多級樹形彈出一個小窗口層(非常好用)實例代碼

    js多級樹形彈出一個小窗口層(非常好用)實例代碼

    js多級樹形彈出一個小窗口層(非常好用)實例代碼,需要的朋友可以參考一下
    2013-03-03
  • JavaScript手寫實現(xiàn)一個簡單的快捷鍵庫

    JavaScript手寫實現(xiàn)一個簡單的快捷鍵庫

    前端開發(fā)中,有時項目會遇到一些快捷鍵需求,比如綁定快捷鍵,展示快捷鍵,編輯快捷鍵等需求,所以本文就來用JavaScript手寫一個簡單的快捷鍵庫吧
    2024-02-02
  • layui 實現(xiàn)表單和文件上傳一起傳到后臺的例子

    layui 實現(xiàn)表單和文件上傳一起傳到后臺的例子

    今天小編就為大家分享一篇layui 實現(xiàn)表單和文件上傳一起傳到后臺的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • JS實現(xiàn)字符串中去除指定子字符串方法分析

    JS實現(xiàn)字符串中去除指定子字符串方法分析

    這篇文章主要介紹了JS實現(xiàn)字符串中去除指定子字符串方法,結(jié)合實例形式分析了javascript使用字符串替換與分割、聚合兩種子字符串去除相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05

最新評論

泽普县| 广丰县| 灌云县| 温州市| 伊金霍洛旗| 大安市| 普安县| 台安县| 志丹县| 昆山市| 抚宁县| 曲阳县| 沛县| 大邑县| 永春县| 交口县| 凌源市| 磴口县| 通化市| 九台市| 会宁县| 平南县| 巴东县| 苍梧县| 宜川县| 咸阳市| 栾城县| 额济纳旗| 霍州市| 泊头市| 安平县| 湟源县| 元朗区| 台山市| 安新县| 孝昌县| 玉环县| 扎赉特旗| 广安市| 芦溪县| 中阳县|