You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
6.7 KiB

name: duk_def_prop
proto: |
void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);
stack: |
[ ... obj! ... key! ] -> [ ... obj! ... ] (if have no value, setter, getter)
[ ... obj! ... key! value! ] -> [ ... obj! ... ] (if have value)
[ ... obj! ... key! getter! ] -> [ ... obj! ... ] (if have getter, but no setter)
[ ... obj! ... key! setter! ] -> [ ... obj! ... ] (if have setter, but no getter)
[ ... obj! ... key! getter! setter! ] -> [ ... obj! ... ] (if have both getter and setter)
summary: |
<p>Create or alter the attributes of property <code>key</code> of object at
<code>obj_idx</code>, with semantics like
<code><a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.6">Object.defineProperty()</a></code>.
When the requested change is not allowed (e.g. property is not configurable), a
<code>TypeError</code> is thrown. If the target is not an object (or the
index is invalid) an error is thrown.</p>
<p>The flags field provides "have" flags to indicate what property attributes
are changed (this models the partial property descriptors allowed by
<code>Object.defineProperty()</code>). Values for the writable, configurable,
and enumerable attributes are given in the flags field, while property value,
getter, and setter are given as value stack arguments. When creating a new
property, missing attribute values cause
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-8.6.1">Ecmascript defaults</a>
to be used (false for all boolean attributes, undefined for value, getter, setter);
when modifying an existing property missing attribute values mean that existing
attribute values are not touched.</p>
<p>With the <code>DUK_DEFPROP_FORCE</code> flag property changes can be forced
even when an operation would normally fail due to a non-extensible target object
or a non-configurable property. This cannot be done from Ecmascript code with
<code>Object.defineProperty()</code> and is useful for e.g. sandboxing setup.
In some cases even a forced change is not possible and will cause an error to be
thrown. For instance, properties implemented internally as virtual properties
may not be modifiable (such as string <code>.length</code> and index properties)
or may have limitations (such as array <code>.length</code> property which cannot
be made configurable or enumerable due to internal limitations).</p>
<p>Some examples (see further examples below):</p>
<ul>
<li>To set the writable attribute, set flags to
<code>DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE</code>.</li>
<li>To clear the writable attribute, set flags to
<code>DUK_DEFPROP_HAVE_WRITABLE</code>.</li>
<li>To set value, clear writable, and set enumerable, set flags to
<code>DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE</code>
and provide the property value as a stack argument.</li>
<li>To forcibly set the value of a non-configurable property, set flags to
<code>DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE</code> and provide the
new property value as a stack argument.</li>
</ul>
<p>In Duktape 1.4.0 convenience flags for setting/clearing attributes were added:</p>
<ul>
<li><code>DUK_DEFPROP_SET_WRITABLE</code> / <code>DUK_DEFPROP_CLEAR_WRITABLE</code></li>
<li><code>DUK_DEFPROP_SET_ENUMERABLE</code> / <code>DUK_DEFPROP_CLEAR_ENUMERABLE</code></li>
<li><code>DUK_DEFPROP_SET_CONFIGURABLE</code> / <code>DUK_DEFPROP_CLEAR_CONFIGURABLE</code></li>
</ul>
<p>This API call is useful for various things:</p>
<ul>
<li>To create properties with non-default attributes directly from C code.</li>
<li>To create accessor (getter/setter) properties directly from C code.</li>
<li>To modify the property attributes of existing properties directly from C code.</li>
</ul>
<p>See API testcase
<a href="https://github.com/svaarala/duktape/blob/master/tests/api/test-def-prop.c">test-def-prop.c</a>
for more examples.</p>
example: |
duk_idx_t obj_idx = /* ... */;
/* Create an ordinary property which is writable and configurable, but
* not enumerable.
*/
duk_push_string(ctx, "my_prop_1");
duk_push_int(ctx, 123); /* prop value */
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |
DUK_DEFPROP_HAVE_ENUMERABLE | 0 |
DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);
/* In Duktape 1.4.0 there are convenience defines to make the above
* more readable.
*/
duk_push_string(ctx, "my_prop_1");
duk_push_int(ctx, 123); /* prop value */
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_SET_WRITABLE |
DUK_DEFPROP_CLEAR_ENUMERABLE |
DUK_DEFPROP_SET_CONFIGURABLE);
/* Change the property value and make it non-writable. Don't touch other
* attributes.
*/
duk_push_string(ctx, "my_prop_1");
duk_push_int(ctx, 321);
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_HAVE_WRITABLE | 0);
/* Make the property non-configurable, don't touch value or other attributes. */
duk_push_string(ctx, "my_prop_1");
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_CONFIGURABLE | 0);
/* Create an accessor property which is non-configurable and non-enumerable.
* Attribute flags are not given so they default to Ecmascript defaults
* (false) automatically.
*/
duk_push_string(ctx, "my_accessor_1");
duk_push_c_function(ctx, my_getter, 0 /*nargs*/);
duk_push_c_function(ctx, my_setter, 1 /*nargs*/);
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_GETTER |
DUK_DEFPROP_HAVE_SETTER);
/* Create an accessor property which is non-configurable but enumerable.
* Attribute flags are given explicitly which is easier to read without
* knowing about Ecmascript attribute default values.
*/
duk_push_string(ctx, "my_accessor_2");
duk_push_c_function(ctx, my_getter, 0 /*nargs*/);
duk_push_c_function(ctx, my_setter, 1 /*nargs*/);
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_GETTER |
DUK_DEFPROP_HAVE_SETTER |
DUK_DEFPROP_HAVE_CONFIGURABLE | /* clear */
DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE); /* set */
/* Change the value of a non-configurable property by force. */
duk_push_string(ctx, "my_nonconfigurable_prop");
duk_push_value(ctx, 321);
duk_def_prop(ctx,
obj_idx,
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_FORCE);
tags:
- property
- sandbox
introduced: 1.1.0