@kingjs/reflect.define-property
v1.0.4
Published
Extends `Reflect.defineProperty` to allow richer descriptors which can include `callback`, `extends`, and `lazy` properties. And `lazy` can be modified by `writeOnce`, `argument`, and `static`.
Downloads
10
Readme
@kingjs/reflect.define-property
Extends Reflect.defineProperty
to allow richer descriptors which can include callback
, extends
, and lazy
properties. And lazy
can be modified by writeOnce
, argument
, and static
.
Usage
var assert = require('assert');
var defineProperty = require('@kingjs/reflect.define-property');
var target = null;
// create descriptor by harvesting name from named function
var { name, descriptor } = defineProperty(
null, function foo() { }
)
assert(name == 'foo');
assert(descriptor.value.name == 'foo');
var target = { };
// harvest name from named function
defineProperty(
target, function foo() { return 0; }
)
assert(target.foo() == 0);
// harvest name from named function in a descriptor
defineProperty(
target, { value: function bar() { return 0; } }
)
assert(target.bar() == 0);
// harvest name from named get/set in a descriptor
defineProperty(
target, { get: function baz() { return 0; } }
)
assert(target.baz == 0);
// wrap get/set in a function
defineProperty(
target, 'lambda', { get: 'this' }
)
assert(target.lambda == target);
// a "readOnly" property can be set only once
defineProperty(
target, 'readOnly', {
get: o => o,
lazy: true,
seeded: true,
static: true, // because target == this at runtime
/* seed: 20 */ // un-comment to provide a default
}
)
target.readOnly = 10;
assert.throws(() => target.readOnly = 20);
assert(target.readOnly == 10);
// wrap value in a function if descriptor is lazy
defineProperty(
target, 'lazyLambda', {
value: 'this.i++',
lazy: true,
static: true, // because target == this at runtime
}
)
target.i = 0;
assert(target.lazyLambda() == 0);
assert(target.lazyLambda() == 0);
// wrap value in a function if descriptor is an extension
var GetLength = Symbol('getLength');
defineProperty(
Object.prototype, GetLength, {
value: 'this.length',
extends: () => String
}
)
assert('foo'.length == 'foo'[GetLength]()); // extends String
assert.throws(() => [ ][GetLength]()) // does not extend Array
// defer creation of descriptor until target and name are known
defineProperty(
target,
'extern', {
callback: (d, n, t) => ({
...d,
get: () => ({
target: t, name: n
})
})
}
)
assert(target.extern.name == 'extern');
assert(target.extern.target == target);
API
defineProperty(target, name, descriptor)
Overloads
defineProperty(target, namedFunction)
=> defineProperty(target, name, { value: namedFunction, ... })
defineProperty(target, { get|set|value: namedFunction, ... })
=> defineProperty(target, name, { get|set|value: namedFunction, ... })
defineProperty(target, name, nonObjectOrNull)
=> defineProperty(target, name, { value: nonObjectOrNull })
Parameters
target
: The target on which the property will be defined.name
: The name of the property.descriptor
: A descriptor which supports these additional properties:descriptor.extends
: A callback that returns a type (function) representing the type being extended. If runtimethis
is not aninstanceof
the type, then an exception is thrown. An extension'sname
must be a symbol and itstarget
must beObject.prototype
.- Returns a function representing the type being extended.
descriptor.lazy
: Caches the result of the property on the runtimethis
.descriptor.seeded
: Modifieslazy
. Allows setting the property with a value that gets passed to the promise when resolved.descriptor.seed
: Modifiesseeded
. If no value is set, thenseed
is used as a default.descriptor.static
: Modifieslazy
. Makes the stub configurable so, if runtimethis
andtarget
are the same object, the stub can be replaced with the cached value.descriptor.callback
: Called just before callingObject.defineProperty
to allow the descriptor to configure itself givenname
andtarget
. The resulting descriptor is passed to a recursive call ofdefineProperty
.descriptor
: A copy of the descriptor.name
: The name of the property.target
: The target on which the property will be defined.- Returns an updated descriptor.
Returns
Returns target
if the property was successfully created. Otherwise undefined
is returned. If target
is null
or undefined
then { name, descriptor }
is returned.
Remarks
- Strings that appear where functions are expected will be wrapped into functions; String values for
get
orset
, orvalue
whenextends
orlazy
is present are wrapped as functions. - Transforms are applied in the order:
lambdize
>extends
>lazy
>callback
. - After applying transforms associated with the properties
callback
,extends
, andlazy
, the corresponding property is deleted from the descriptor. This can only be seen if notarget
is supplied causing the descriptor to be returned.
See Also
Install
With npm installed, run
$ npm install @kingjs/reflect.define-property
Dependencies
|Package|Version|
|---|---|
|@kingjs/is
|^1.0.9
|
|@kingjs/property-descriptor.lambdize
|^1.0.2
|
|@kingjs/property-descriptor.make-lazy
|^1.0.3
|
|@kingjs/property-descriptor.target-instance-of
|^1.0.3
|
Source
https://repository.kingjs.net/reflect/define-property
License
MIT