333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
'use strict';
const isObj = require('is-obj');
 
function getPathSegments(path) {
    const pathArr = path.split('.');
    const parts = [];
 
    for (let i = 0; i < pathArr.length; i++) {
        let p = pathArr[i];
 
        while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) {
            p = p.slice(0, -1) + '.';
            p += pathArr[++i];
        }
 
        parts.push(p);
    }
 
    return parts;
}
 
module.exports = {
    get(obj, path, value) {
        if (!isObj(obj) || typeof path !== 'string') {
            return value === undefined ? obj : value;
        }
 
        const pathArr = getPathSegments(path);
 
        for (let i = 0; i < pathArr.length; i++) {
            if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) {
                return value;
            }
 
            obj = obj[pathArr[i]];
 
            if (obj === undefined || obj === null) {
                // `obj` is either `undefined` or `null` so we want to stop the loop, and
                // if this is not the last bit of the path, and
                // if it did't return `undefined`
                // it would return `null` if `obj` is `null`
                // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
                if (i !== pathArr.length - 1) {
                    return value;
                }
 
                break;
            }
        }
 
        return obj;
    },
 
    set(obj, path, value) {
        if (!isObj(obj) || typeof path !== 'string') {
            return obj;
        }
 
        const root = obj;
        const pathArr = getPathSegments(path);
 
        for (let i = 0; i < pathArr.length; i++) {
            const p = pathArr[i];
 
            if (!isObj(obj[p])) {
                obj[p] = {};
            }
 
            if (i === pathArr.length - 1) {
                obj[p] = value;
            }
 
            obj = obj[p];
        }
 
        return root;
    },
 
    delete(obj, path) {
        if (!isObj(obj) || typeof path !== 'string') {
            return;
        }
 
        const pathArr = getPathSegments(path);
 
        for (let i = 0; i < pathArr.length; i++) {
            const p = pathArr[i];
 
            if (i === pathArr.length - 1) {
                delete obj[p];
                return;
            }
 
            obj = obj[p];
 
            if (!isObj(obj)) {
                return;
            }
        }
    },
 
    has(obj, path) {
        if (!isObj(obj) || typeof path !== 'string') {
            return false;
        }
 
        const pathArr = getPathSegments(path);
 
        for (let i = 0; i < pathArr.length; i++) {
            if (isObj(obj)) {
                if (!(pathArr[i] in obj)) {
                    return false;
                }
 
                obj = obj[pathArr[i]];
            } else {
                return false;
            }
        }
 
        return true;
    }
};