// โญ๏ธ 1. prop: invalid identifier
// ------------------------------
undeclared ?. 1 = 'bad'; // โ SyntaxError: Unexpected token
// ^
// โญ๏ธ 2. obj: "undeclared"
// -------------------------------
undeclared ?. prop; // โ ReferenceError: 'undeclared' is not defined
// โญ๏ธ 3. obj: "nullish"
// -------------------------------
null ?. prop // โ undefined
// โญ๏ธ 4. obj: not "nullish"
// -------------------------------
(18) ?. prop; // โ undefined (no such `prop`)
(18) ?. toString(16); // โ "12" (property value, could be any value)
// test object
let person = {
name : 'Tom',
age : 28,
address: { street: 'Fifth Ave.', no: '23' },
hobbies: ['TV', 'Game'],
eat(food) { return 'poop' }
};
'------------ person ------------',
// โ "root" object (person) is NEVER protected
person ?. name, // "Tom"
// โฐ๐ก๏ธโฏ
person ?. hobby, // undefined
// โฐ๐ก๏ธโโฏ
person ?. address ?. street, // "Fifth Ave."
// โฐโ๐ก๏ธโโโฏ โฐโ๐ก๏ธโโฏ
person . address ?. district, // undefined (โ address: non-nullish)
// โฐโโโโโฏ โฐโโ๐ก๏ธโโโฏ
person . hobby ?. [1], // undefined (โ hobby: nullish, protected)
// โฐโโโฏ โฐ๐ก๏ธโฏ
person . hobbies ?. [2], // undefined (โ hobbies: non-nullish)
// โฐโโโโโฏ โฐ๐ก๏ธโฏ
person ?. eat ?. ('egg'), // "poop" (โ eat: non-nullish)
// โฐ๐ก๏ธโฏ โฐโ๐ก๏ธโโโฏ
person ?. make ?. (something), // undefined (โ make: direct prop, protected, short-circuiting)
// โฐ๐ก๏ธโโฏ โฐโโโ๐ก๏ธโโโโโฏ
// jane
let jane = {
home : null,
boyfriend: { name: 'Joe' }
};
'------------ jane ------------',
// โ "root" object (jane) is NEVER protected
jane . home, // null (prop value)
// โฐโโฏ
jane ?. home, // null (jane: non-nullish, = jane.home)
// โฐ๐ก๏ธโฏ
// ๐ก๏ธ: "?." protect "nullish" obj and "direct" prop
// โ: no protection, could be undeclared / nullish / error
// -----------------------------------------------------------
jane . home ?. c , // undefined (โ home: null, protected)
// โฐโโฏ โฐ๐ก๏ธโฏ
jane . home ?. ['hello'], // undefined (โ home: null, protected)
// โฐโโฏ โฐโโโ๐ก๏ธโโโโฏ
jane . home ?. c . d , // undefined (โ home: null, short-circuiting)
// โฐโโฏ โฐ๐ก๏ธโฏ โฐโโฏ
// โญโ UD โโฎ // UD: UnDefined
// (a.b?.c).d, // โ DON'T DO THIS! (โ TypeErrorโ)
// ^
jane . boyfriend ?. name, // 'Joe' ( โ boyfriend: non-nullish)
// โฐโโโโโโโฏ โฐ๐ก๏ธโฏ
jane . boyfriend ?. money, // undefine ( โ money: direct prop, protected)
// โฐโโโโโโโฏ โฐ๐ก๏ธโโฏ
jane . boyfriend ?. money . more, // โ TypeError (accessing `undefined.more`)
// โฐโโโโโโโฏ โฐ๐ก๏ธโโฏ โฐโโโฏ // (โ more: not protected)
jane . boyfriend ?. money ?. more, // undefined โ (more: direct prop, protected)
// โฐโโโโโโโฏ โฐ๐ก๏ธโโฏ โฐ๐ก๏ธโโฏ
โญ๏ธ the variable before ?.must be declaredโ๏ธ
// โญโโโโ๏ธโโโโฎ <----- โญ๏ธ "root" object is NEVER protectedโ๏ธ
undeclared?.address;
// โ ReferenceError: `undeclared` is not defined
// ๐ก๏ธ "?." only protects "nullish obj" and "direct prop"
// โ "." provides NO protection.
// โ "root" object is NEVER protected.
jane . boyfriend ?. name // โ boyfriend: non-nullish, ok.
// โฐโโโโโโโฏ โฐ๐ก๏ธโฏ
jane . boyfriend ?. money . more // โ money: direct prop, protected.
// โฐโโโโโโโฏ โฐโ๐ก๏ธโโฏ โฐโโฏ // โ more: not protected, error may occur.
โญ๏ธ use ?. for reading / deleting, but notwritingโ๏ธ
user?.name // โ read if exists
delete user?.name // โ delete if exists.
user?.name = "John" // โ SyntaxError
// Invalid left-hand side in assignment
// this is literally `undefine = "John"`โ๏ธ
let a = { b: null };
a.b?.c.d, // โ this is OK (โญ "short-circuiting" works.)
// โญโ UD โโฎ // UD: undefined
(a.b?.c).d, // โ DON'T DO THIS! (โ TypeErrorโ)
// ^
const city = user ?. city ?? "Unknown city"
// โฐโโ O.C. โโโฏ โฐโ default โโโฏ