1 the introduction
Object type comparison is very important basic knowledge, through How to Compare Objects in JavaScript this article, we can learn four comparison methods: reference comparison, manual comparison, shallow comparison, deep comparison.
2 brief introduction
Reference contrast
The following three comparison methods are used for Object, and return true only if all references are the same:
= = =
= =
Object.is()
const hero1 = {
name: "Batman".};
const hero2 = {
name: "Batman".}; hero1 === hero1; // => true hero1 === hero2; // => false hero1 == hero1; // => true hero1 == hero2; // => false Object.is(hero1, hero1); // => true Object.is(hero1, hero2); // => false Copy the code
Manual contrast
Another option is to write a custom function that makes a custom comparison based on the object’s contents:
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 Copy the code
This manual comparison can be useful if there are not many object keys to compare, or if a particular business scenario requires it.
But this scheme is not automated enough, so there is a shallow contrast.
Light contrast
There are many ways to write a shallow contrast function, but its effect is standard, the following is a way to write:
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; } Copy the code
As you can see, shallow comparison refers to the comparison of each attribute of the object, which is a kind of performance balance, especially under Redux.
Examples are given below:
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 Copy the code
If there is one more level of the object hierarchy, shallow contrast is ineffective, and deep contrast is needed.
Deep contrast
Deep comparison refers to the recursive comparison of all simple object values, the comparison of complex objects by key, and so on.
Here’s one way to do it:
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) { returnobject ! =null && typeof object === "object"; } Copy the code
As you can see, deepEqual is recursively called whenever an Object key is encountered, otherwise it is used directly for simple types! == Reference comparison.
Keys can be used on arrays, and object[key] can be used on arrays, so arrays and objects can be treated in the same way.
With deep comparisons, you no longer have to worry about complex object comparisons:
const hero1 = {
name: "Batman". address: {
city: "Gotham". },
}; const hero2 = { name: "Batman". address: { city: "Gotham". }, }; deepEqual(hero1, hero2); // => true Copy the code
However, deep comparisons can cause performance losses. Don’t underestimate the power of recursion, and deep comparisons can even cause serious performance problems when the object tree is complex.
3 intensive reading
Common reference contrast
Reference comparison is the most commonly used. Generally, only reference comparison is allowed when comparing props:
this.props.style ! == nextProps.style;Copy the code
If you see a place with deep contrast, you should be alert. Is deep contrast really needed here? Is there something wrong with writing it elsewhere?
For example, somewhere you see code like this:
deepEqual(this.props.style, nextProps.style);
Copy the code
May be caused by a random spelling of the parent component:
const Parent = (a)= > {
return <Child style={{ color: "red}} "/ >;
};
Copy the code
A student who only solves a local problem might use deepEqual. OK will also solve the problem, but a student with a global sense will solve the problem like this:
this.props.style === nextProps.style;
Copy the code
const Parent = (a)= > {
const style = useMemo((a)= > ({ color: "red" }), []);
return <Child style={style} />;
};
Copy the code
From a performance point of view, the Parent style is executed only once and the next render has almost no contrast loss (dependent on empty arrays), and the subcomponent reference contrast performs best, which is certainly better than the deepEqual example.
Common shallow contrast
Light contrast is also used to determine if a component is being rerendered:
shouldComponentUpdate(nextProps) {
return! shallowEqual(this.props, nextProps)
}
Copy the code
This. Props [key] is only used in the React component ecosystem. This. The Immutable context guarantees that any change in an object’s subproperties will result in a change in the object’s overall reference, making it safe to make shallow comparisons.
The rarest are manual contrast and deep contrast. If you see a piece of code that uses deep contrast, chances are the code can be optimized for shallow contrast.
4 summarizes
Although there are four ways to compare objects today, in real projects, reference comparison should be used whenever possible, followed by shallow comparison, manual comparison, and, at worst, deep comparison.
How to compare objects · Issue #258 · dt-fe/weekly
If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.
Pay attention to the front end of intensive reading wechat public account
Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)