cd /news/developer-tools/javascript-property-behavior-matrix · home topics developer-tools article
[ARTICLE · art-83318] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

JavaScript Property Behavior Matrix

A new JavaScript reference document, created by AI in collaboration with a user, provides a comprehensive matrix of how property types—enumerable vs non-enumerable, string vs symbol, and own vs inherited—interact with operators, loops, spread, and Object static methods. The matrix clarifies behaviors such as property access, assignment, deletion, and copying, highlighting distinctions like masking inherited properties and the exclusion of non-enumerable and symbol keys in certain operations.

read4 min views1 publishedAug 1, 2026

A comprehensive reference for how JavaScript property types interact with language operators, loops, spread, and Object static methods.

Document Note:Created by AI (Gemini) in collaboration with the user.

Enum vs Non-Enum: Refers to property enumerability (enumerable: true vsenumerable: false

),notTypeScriptenum

types.String vs Symbol: Refers to the property key type (String keys like"a"

vs Symbol keys likeSymbol("a") ).Own vs Inherited: Properties defined directly on the object instance vs properties inherited through the prototype chain.

— Property value is evaluated. If it's an accessor, its✓ Accessed

Getter is executed.— Existing own property value is updated (invokes an own✓ Overwritten

Setter if defined).— Assignment creates a new⬖ Masked

own data property onobj

, masking the prototype (or invokes an inheritedSetter if defined).✓ Deleted

— Own property is removed from the object.1— Key exists and is detected (✓ Found true

returned by existence check).— Property is included in the output array or loop iteration. For✓ Included

`Object.values()`

and`Object.entries()`

, reading the value invokesGetters if present.— Value is evaluated (executing✓ Copied

Getters if present) and assigned as a data property.— Raw descriptor object✓ Described

{ get, set, value, ... } is read directly without invoking accessors.— Property is skipped/bypassed (or returns✗ Ignored

false

on existence checks, same as for missing properties).

| Situation / Operation | Own String (Enum) | Own String (Non-Enum) | Own Symbol (Enum) | Own Symbol (Non-Enum) | Inherited String (Enum) | Inherited (Non-Enum or Symbol) |
|---|---|---|---|---|---|---|
`val = obj.prop` / `val = obj[prop]` |

✓ Accessed | ✓ Accessed | ✓ Accessed | ✓ Accessed | ✓ Accessed | ✓ Accessed | obj.prop = val / obj[prop] = val | ✓ Overwritten | ✓ Overwritten | ✓ Overwritten | ✓ Overwritten | ⬖ Masked | ⬖ Masked | delete obj.prop / delete obj[prop] | ✓ Deleted | ✓ Deleted | ✓ Deleted | ✓ Deleted | ✗ Ignored | ✗ Ignored | prop in obj | ✓ Found | ✓ Found | ✓ Found | ✓ Found | ✓ Found | ✓ Found | Object.hasOwn(obj, prop) / obj.hasOwnProperty(prop) | ✓ Found | ✓ Found | ✓ Found | ✓ Found | ✗ Ignored | ✗ Ignored | for (prop in obj) | ✓ Included | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✓ Included | ✗ Ignored | Object.keys() / Object.values() / Object.entries() | ✓ Included | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | { ...obj } | ✓ Copied | ✗ Ignored | ✓ Copied | ✗ Ignored | ✗ Ignored | ✗ Ignored | Object.assign(target, src) | ✓ Copied | ✗ Ignored | ✓ Copied | ✗ Ignored | ✗ Ignored | ✗ Ignored | structuredClone(obj) | ✓ Copied | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | JSON.stringify(obj) | ✓ Copied | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | Object.getOwnPropertyNames(obj) | ✓ Included | ✓ Included | ✗ Ignored | ✗ Ignored | ✗ Ignored | ✗ Ignored | Object.getOwnPropertySymbols(obj) | ✗ Ignored | ✗ Ignored | ✓ Included | ✓ Included | ✗ Ignored | ✗ Ignored | Reflect.ownKeys(obj) | ✓ Included | ✓ Included | ✓ Included | ✓ Included | ✗ Ignored | ✗ Ignored | Object.getOwnPropertyDescriptor / Object.getOwnPropertyDescriptors | ✓ Described | ✓ Described | ✓ Described | ✓ Described | ✗ Ignored | ✗ Ignored |

Footnotes #

delete

Operator Return Values & Mechanics:delete

only affectsown properties, leaving inherited prototype properties untouched (and returningtrue

). It returnstrue

if an own property was successfully deleted, or if the property never existed in the first place. It returnsfalse in non-strict mode (or throws aTypeError

in strict mode) when attempting to delete an**own non-configurable property**.[↩](https://gist.github.com/starred.atom#user-content-fnref-1-bacf6fede3ac5ab18924c7e40bf71080) -
While both copy values (invoking Getters on`Object.assign`

vs. Object Spread (`{ ...obj }`

):`src`

),`Object.assign(target, src)`

assigns values totarget

viatarget[k] = val . Thus, it triggersSetters iftarget

(or its prototype chain) already defines a matching setter. Spread ({ ...src } ) always defines newown data properties on the object literal being constructed, completely bypassing any existing target setters.2 - Executes Getters on own enumerable string properties and recursively deep-clones values.structuredClone(obj)

Constraints:Throws a if any property value is aDataCloneError

Function orMethod. Symbols, non-enumerable properties, and prototype chains are completely stripped. - Executes Getters on own enumerable string properties. AutomaticallyJSON.stringify(obj)

Constraints:omits properties whose value evaluates to aFunction,** Symbol**, orundefined

(when inside objects), or converts them tonull

(when inside arrays).

── more in #developer-tools 4 stories · sorted by recency
── more on @javascript 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/javascript-property-…] indexed:0 read:4min 2026-08-01 ·