obj.prop(path)
如果 JavaScript 引擎不支援 optional chaining (?., ?.[]),就可以用下面的程式。
由於使用 mixin 的方式,所以當我們使用 user.prop('info.age')
的方式來讀取物件屬性時,user
本身已經確定是個物件(不會是 null 或 undefined),因此我們在 prop(path)
這個 method 內部並沒有去檢查 this
是不是 null 或 undefined。
replit ⟩ obj.prop(path)
// ⭐ mixin for objects
const ObjectTools = {
// obj.prop(path)
prop(path) {
let value = this;
let components = path.split('.');
while (components.length) {
// pull first component
let component = components.shift();
// check if last character === '?'
const isValueOptional = component.slice(-1) === '?';
if (isValueOptional) {
// remove "?"
component = component.slice(0, -1);
// get nested property
value = value[component];
// return early if value is nullish
if (value === null || value === undefined) return undefined;
} else {
// if not optional, get property directly
value = value[component];
}
}
return value;
}
};
// for node.js module
module.exports = objectTools;
💈範例:
"use strict";
const { log } = console;
// ⭐ mixin for objects
const ObjectTools = require('./ObjectTools.js');
// ---------- main ------------
// test object
const user = {
name: 'Joy',
info: {
address: {
street: '5th Street',
zip: 333,
}
}
};
// ⭐ apply mixin to `obj`
Object.assign(user, ObjectTools);
// ---------- log ------------
;
[
user.prop("info.address"), // { street: '5th Street', zip: 333 }
user.prop("info.address.street"), // '5th Street'
user.prop("info.address.street.bar"),// undefined
user.prop("info.age"), // undefined
user.prop("info.age?.details"), // undefined
user.prop("bar?.age?.details"), // undefined
// user.prop("bar.age"), // ⛔ TypeError:
// ^^^ <---- Cannot read property 'age' of undefined
user === global.user, // false: `const` doesn't create property of `global`
].forEach(x => log(x));
// user.prop("info.address.street")
// ---------------------------------
// initial states:
//
// • value = user
// • components = [ 'info', 'address', 'street' ]
//
// while loop:
// --------------------------------------------------------------------
// length shift() components value
// --------------------------------------------------------------------
// 3 'info' ['address', 'street'] user.info
// 2 'address' ['street'] user.info.address
// 1 'street' [ ] user.info.address.street
// 0 <---- exit while loop ╰── return value ───╯
// --------------------------------------------------------------------
Global object unlike
var
,let
andconst
do not create properties of the global object.
use the concept of mixin.
Last updated