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.

Required Knowledge

Related Katas

Reflect

Difficulty Level

INTERMEDIATE

First Published

31 July 2015

Stats

15 tests to solve