go检测出json中的duplicate object key_精读《如何比较 Object 对象》
1 引言
Object 類型的比較是非常重要的基礎知識,通過 How to Compare Objects in JavaScript 這篇文章,我們可以學到四種對比方法:引用對比、手動對比、淺對比、深對比。
2 簡介
引用對比
下面三種對比方式用于 Object,皆在引用相同是才返回 true:
- ===
- ==
- Object.is()
手動對比
寫一個自定義函數,按照對象內容做自定義對比也是一種方案:
function isHeroEqual(object1, object2) {return object1.name === object2.name; }const hero1 = {name: "Batman", }; const hero2 = {name: "Batman", }; const hero3 = {name: "Joker", };isHeroEqual(hero1, hero2); // => true isHeroEqual(hero1, hero3); // => false如果要對比的對象 key 不多,或者在特殊業務場景需要時,這種手動對比方法其實還是蠻實用的。
但這種方案不夠自動化,所以才有了淺對比。
淺對比
淺對比函數寫法有很多,不過其效果都是標準的,下面給出了一種寫法:
function shallowEqual(object1, object2) {const keys1 = Object.keys(object1);const keys2 = Object.keys(object2);if (keys1.length !== keys2.length) {return false;}for (let key of keys1) {if (object1[key] !== object2[key]) {return false;}}return true; }可以看到,淺對比就是將對象每個屬性進行引用對比,算是一種性能上的平衡,尤其在 redux 下有特殊的意義。
下面給出了使用例子:
const hero1 = {name: "Batman",realName: "Bruce Wayne", }; const hero2 = {name: "Batman",realName: "Bruce Wayne", }; const hero3 = {name: "Joker", };shallowEqual(hero1, hero2); // => true shallowEqual(hero1, hero3); // => false如果對象層級再多一層,淺對比就無效了,此時需要使用深對比。
深對比
深對比就是遞歸對比對象所有簡單對象值,遇到復雜對象就逐個 key 進行對比,以此類推。
下面是一種實現方式:
function deepEqual(object1, object2) {const keys1 = Object.keys(object1);const keys2 = Object.keys(object2);if (keys1.length !== keys2.length) {return false;}for (const key of keys1) {const val1 = object1[key];const val2 = object2[key];const areObjects = isObject(val1) && isObject(val2);if ((areObjects && !deepEqual(val1, val2)) ||(!areObjects && val1 !== val2)) {return false;}}return true; }function isObject(object) {return object != null && typeof object === "object"; }可以看到,只要遇到 Object 類型的 key,就會遞歸調用一次 deepEqual 進行比較,否則對于簡單類型直接使用 !== 引用對比。
值得注意的是,數組類型也滿足 typeof object === "object" 的條件,且 Object.keys 可以作用于數組,且 object[key] 也可作用于數組,因此數組和對象都可以采用相同方式處理。
有了深對比,再也不用擔心復雜對象的比較了:
const hero1 = {name: "Batman",address: {city: "Gotham",}, }; const hero2 = {name: "Batman",address: {city: "Gotham",}, };deepEqual(hero1, hero2); // => true但深對比會造成性能損耗,不要小看遞歸的作用,在對象樹復雜時,深對比甚至會導致嚴重的性能問題。
3 精讀
常見的引用對比
引用對比是最常用的,一般在做 props 比較時,只允許使用引用對比:
this.props.style !== nextProps.style;如果看到有深對比的地方,一般就要有所警覺,這里是真的需要深對比嗎?是不是其他地方寫法有問題導致的。
比如在某處看到這樣的代碼:
deepEqual(this.props.style, nextProps.style);可能是父組件一處隨意拼寫導致的:
const Parent = () => {return <Child style={{ color: "red" }} />; };一個只解決局部問題的同學可能會采用 deepEqual,OK 這樣也能解決問題,但一個有全局感的同學會這樣解決問題:
this.props.style === nextProps.style;const Parent = () => {const style = useMemo(() => ({ color: "red" }), []);return <Child style={style} />; };從性能上來看,Parent 定義的 style 只會執行一次且下次渲染幾乎沒有對比損耗(依賴為空數組),子組件引用對比性能最佳,這樣的組合一定優于 deepEqual 的例子。
常見的淺對比
淺對比也在判斷組件是否重渲染時很常用:
shouldComponentUpdate(nextProps) {return !shallowEqual(this.props, nextProps) }原因是 this.props 這個對象引用的變化在邏輯上是無需關心的,因為應用只會使用到 this.props[key] 這一層級,再考慮到 React 組件生態下,Immutable 的上下文保證了任何對象子屬性變化一定導致對象整體引用變化,可以放心的進行淺對比。
最少見的就是手動對比和深對比,如果你看到一段代碼中使用了深對比,大概率這段代碼可以被優化為淺對比。
4 總結
雖然今天總結了 4 種比較 Object 對象的方式,但在實際項目中,應該盡可能使用引用對比,其次是淺對比和手動對比,最壞的情況是使用深對比。
討論地址是:精讀《如何比較 Object 對象》》· Issue #258 · dt-fe/weekly如果你想參與討論,請 點擊這里,每周都有新的主題,周末或周一發布。前端精讀 - 幫你篩選靠譜的內容。
關注 前端精讀微信公眾號版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證)總結
以上是生活随笔為你收集整理的go检测出json中的duplicate object key_精读《如何比较 Object 对象》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ccxt k线数据_机器学习系列:深度探
- 下一篇: 创维oled工厂模式abd_创维OLED