jskatas.org Continuously Learn JavaScript. Your Way.

Reflect: Reflect.defineProperty()

Defines a property on a given object.

Reflect.defineProperty() is like Object.defineProperty() but returns a Boolean.

the function itself

is static on the Reflect object
const name = 'what`s the functions name again? :)'; assert.equal(name in Reflect, true);
is of type function
const actualType = ''; assert.equal(actualType, typeof Reflect.defineProperty)

the 1st parameter is the object on which to define a property

fails if it is not an object
let noObj = {}; assert.throws(() => { Reflect.defineProperty(noObj, 'property', {value: 'value'}); });
accepts an object
let obj = ''; assert.doesNotThrow(() => { Reflect.defineProperty(obj, 'property', {value: 'value'}); });
accepts an instance (of a class)
let instance; assert.doesNotThrow(() => { Reflect.defineProperty(instance, 'property', {value: 'value'}); });

2nd parameter is the name of the property to be defined on the object (normally a string)

works with a normal string
let obj = {}; Reflect.defineProperty(obj, '', {}); assert.equal('prop' in obj, true);
a number gets converted into a string
let obj = {}; Reflect.defineProperty(obj, 2, {}); assert.equal('1' in obj, true);
undefined also gets converted into a string (watch out!)
let obj = {}; let undef = 1; Reflect.defineProperty(obj, undef, {}); assert.equal('undefined' in obj, true);
it can be a symbol
let obj = {}; const sym = Symbol.for('prop'); Reflect.defineProperty(obj, 'prop', {}); assert.equal(sym in obj, true);

the value is part of the 3rd parameter, given as a property in an object {value: ...}

contains the initial value of the property, as an object in the property value
let obj = {}; Reflect.defineProperty(obj, 'prop'); assert.equal(obj.prop, 'property value');
can be of any type (even itself)
let obj = {}; Reflect.defineProperty(obj, 'prop'); assert.equal(obj.prop, obj);

the return value of the function indicates wether the property was defined successfully

returns true

when the property was created (which requires the 3rd parameter too!!!)
let instance = new class {}; const wasPropertyDefined = Reflect.defineProperty(); assert.equal(wasPropertyDefined, true);
no matter what the value of the property is (just the 3rd param has to exist as `{}')
let instance = new class {}; const wasPropertyDefined = Reflect.defineProperty(instance); assert.equal(wasPropertyDefined, true);

returns false

when a non-configurable property wants to be changed to configurable=true
let obj = {}; Reflect.defineProperty(obj, 'x', {configurable: false}); const wasPropertyDefined = Reflect.defineProperty; assert.equal(wasPropertyDefined, false);
when the object we want to add a property to is frozen
let instance = new class {}; Object.freeze(instance); const wasPropertyDefined = Reflect.defineProperty({}, 'prop', {value: 1}); assert.equal(wasPropertyDefined, false);

Links

The specification for this function.
The MDN docs for this function.
Announcement of this kata on twitter.