Making a total base: www.github.com/dashnowords…

Blog park address: “Da Shi lives in big front” original blog directory

Nuggets address: juejin.cn/user/294634…

Huawei cloud community address: [you want to play strange front-end upgrade guide]

Bytedance Happiness big front end team invites all the best to come and play, the team is harmonious and loving, the technology is hardcore, the bytefan is positive, covering the front end of all directions of the technology stack, there is always a place for you, Base Beijing, social recruitment internship has HC, do not hesitate, please directly aim at [email protected]~

[TOC]

Sample code:

let { a = [] } = b || {};
   a.map(item= > {
   item.headerTpl = buildHeader(item);
});
Copy the code

Problem analysis:

The default value (empty array) given in the deconstruction of A will take effect only when the value of b.A is undefined. If the value of B.A is null, the default value will not take effect, so that the code calling map method in the second line will directly report an error, so the first line of code is not fully equipped.

Option 1 — the lodash.get method

Conclusion: The unified use of loDash methods for value mining and subsequent processing, such as _.map(), can basically avoid too much checksum defense code in the business layer, and LoDash API semantics are relatively clear, easy to understand the developer’s intention. However, if it works with ES6 native methods, you will need to continue to do fault tolerance to avoid null pits.

• If there is null or undefined in the path, the default value is returned instead of an error message, even if there are subsequent value paths

• If the value is null, null is returned (the default is not triggered), so if you want to call a native array method of the expected type, you still need to be type tolerant. If you want to call a native array method of the expected type, you do not need to be type tolerant with other methods provided by LoDash.

API and source address: lodash.com/docs/4.17.1…

const get = require('lodash/get');
const response = {
    "data": {
        "history": [{
            "date": "2020-09-11"."eat": 0."sleep": 0."total": {
                "student1": {
                    "eat": 9."sleep": 0}}}, {"date": "2020-08-21"."eat": 0."sleep": 53."total": {
                "student1": {
                    "eat": 0."sleep": 13
                },
                "student1": {
                    "eat": 0."sleep": 53}}}]."test": {"test_undefined": undefined."test_null": null}},"message": "success"."status": 0
}
// Conventional values
let result1=get(response,'data.history[1].total.student1'.'defaultValue');
let result2=get(response,'data.history[3].total.student1'.'defaultValue');
let result3 = get(response, 'data.test.test_undefined'.'defaultValue');
let result4 = get(response, 'data.test.test_null'.'defaultValue');
let result5 = get(response, 'data.test.test_undefined.lark'.'defaultValue');
let result6 = get(response, 'data.test.test_null.lark'.'defaultValue');
console.log(result1); // {eat:0, sleep:13}
console.log(result2); // defaultValue
console.log(result3); //defaultValue
console.log(result4); //null
console.log(result5); //defaultValue
console.log(result6); //defaultValue
Copy the code

Option 2 — Use the Babel optional chain plug-in

Conclusion: The implementation principle and syntax are simplified, which can better match with ES6 native method.

• If there is null or undefined in the path, the default value is returned instead of an error message, even if there are subsequent value paths

• Return the default value when the final result is undefined or null (the difference with lodash.get)

• Description of optional chains in MDN

First configure the Babel plug-in:

{
 "plugins": [
    "@babel/plugin-proposal-nullish-coalescing-operator"."@babel/plugin-proposal-optional-chaining"]}Copy the code

Use optional chains in code:

const response = {
    "data": {
        "history": [{
            "date": "2020-09-11"."eat": 0."sleep": 0."total": {
                "student1": {
                    "eat": 9."sleep": 0}}}, {"date": "2020-08-21"."eat": 0."sleep": 53."total": {
                "student1": {
                    "eat": 0."sleep": 13
                },
                "student2": {
                    "eat": 0."sleep": 53}}}]."test": {"test_undefined": undefined."test_null": null}},"message": "success"."status": 0
}
letresult1 = response.data? .history[1]? .total? .student1 ??'defaultValue';
letresult2 = response.data? .history[3]? .total? .student1 ??'defaultValue';
letresult3 = response.data? .test? .test_undefined ??'defaultValue';
letresult4 = response.data? .test? .test_null ??'defaultValue';
letresult5 = response.data? .test? .test_undefined? .lark ??'defaultValue';
letresult6 = response.data? .test? .test_null? .lark ??'defaultValue';
console.log(result1); // {eat:0, sleep:13}
console.log(result2); // defaultValue
console.log(result3); // defaultValue
console.log(result4); // defaultValue
console.log(result5); // defaultValue
console.log(result6); // defaultValue
Copy the code

Scenario 3 — Use functional programming to implement the GET method

How to gracefully and securely value values in deep data structures

/ * * * *@param {*} p ['a','b'....] Attribute path *@param {*} O The object to be specified *@param {*} D defaultValue defaultValue */
const get = (p, o, d) = > p.reduce((xs, x) = > (xs && xs[x]) ? xs[x] : d, o);
Copy the code

The result of compiling the Babel optional chain:

The source code:

const a = {
  b: {
    c: {
      d: null}}};letr = a.b? .c? .d ??"defaultValue";
Copy the code

The compiled:

var _a$b$c$d, _a$b, _a$b$c;
const a = {
  b: {
    c: {
      d: null}}};let r = (_a$b$c$d = (_a$b = a.b) === null || _a$b === void 0 ? void 0 : (_a$b$c = _a$b.c) === null || _a$b$c === void 0 ? void 0: _a$b$c.d) ! = =null&& _a$b$c$d ! = =void 0 ? _a$b$c$d : "defaultValue";
Copy the code

The basic logic, which can be viewed from the inside out in parentheses, is not complicated, except that undefined and NULL are fault-tolerant each time an attribute is fetched.