JS_InitClass

  • Revision slug: SpiderMonkey/JSAPI_Reference/JS_InitClass
  • Revision title: JS_InitClass
  • Revision id: 26496
  • Created:
  • Creator: Jorend
  • Is current revision? No
  • Comment no wording changes

Revision Content

Make a JSClass accessible to JavaScript code by creating its prototype, constructor, properties, and functions.

Syntax

JSObject * JS_InitClass(JSContext *cx, JSObject *obj,
    JSObject *parent_proto, JSClass *clasp,
    JSNative constructor, uintN nargs,
    JSPropertySpec *ps, JSFunctionSpec *fs,
    JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
Name Type Description
cx JSContext * Pointer to a JS context from which to derive runtime information. {{ Jsapi-requires-request() }}
obj JSObject * Pointer to the "globals" object to use for initializing the class. This must not be NULL. Once JS_InitClass creates the new class's constructor, it stores the constructor as a property in this object. So, for example, if this object is JS_GetGlobalObject(cx), then JavaScript code will be able to see the new class as a global name.
parent_proto JSObject * Pointer to an object to be used as a prototype. JS_InitClass always creates a new prototype object that serves as the __proto__ for class instances; parent_proto becomes the __proto__ of that prototype object.
clasp JSClass * Pointer to the class structure to initialize. This structure defines the class for use by other API functions.
constructor JSNative The constructor for the class. Its scope matches that of the obj argument. If constructor is NULL, then static_ps and static_fs must also be NULL.
nargs uintN Number of arguments for the constructor.
ps JSPropertySpec * Either NULL or a pointer to an array of JSPropertySpecs, terminated by the null JSPropertySpec, which can be written {0, 0, 0, 0, 0}. These properties, if any, are added to the class's new prototype object. All instances of the new class will inherit these properties via the prototype chain.
fs JSFunctionSpec * Either NULL or a pointer to an array of JSFunctionSpecs, terminated by JS_FS_END. These functions, if any, are added to the class's new prototype object. All instances of the new class will inherit these methods via the prototype chain. (This is the JavaScript equivalent of public, non-static methods in C++ or Java.)
static_ps JSPropertySpec * Either NULL or a pointer to an array of JSPropertySpecs, terminated by the null JSPropertySpec. These properties, if any, are added to the new class's constructor. (This is the nearest JavaScript equivalent of public static member variables in C++ or public static fields in Java.)
static_fs JSFunctionSpec * Either NULL or a pointer to an array of JSFunctionSpecs, terminated by JS_FS_END. These functions, if any, are added to the new class's constructor. (This is the JavaScript equivalent of public static methods in C++ or Java.)

Description

JS_InitClass initializes a JSClass and (optionally) makes it visible to JavaScript code.

This is one way to create JSObjects whose properties and methods are implemented in native C/C++. If you need a native function but you don't need to support instances or inheritance, JS_InitClass might be overkill. JS_DefineFunction is simpler.

A JSAPI class consists of a JSClass structure, a constructor, a prototype object, and properties and functions. The JSClass is an internal data structure that is not exposed outside the JavaScript engine. It specifies the name of the class, its flags, and its property access functions. These include native C functions for instance finalization, adding and deleting properties, getting and setting property values, and enumerating, converting, and resolving properties. The JSAPI provides reasonable default behavior for all of these; ordinarily you don't want to overload any of them.

After a successful call to JS_InitClass, JavaScript code can see and manipulate the class's constructor and prototype just as if it were an ordinary JavaScript function with a prototype property. JavaScript code can create new instances using the new keyword. Classes can have methods and properties that are present on all instances. They can also have methods and properties that are only present on the constructor; these are called "static methods" and "static properties" because they serve the same purpose and use the same syntax as static methods and fields in Java.

On success, JS_InitClass returns a pointer to a JS object that is the prototype for the newly initialized class. If JS_InitClass fails, it returns NULL.

The constructor for the class is built in the same context as cx, and in the same scope as obj. If you pass NULL as the constructor parameter, then a constructor is not built, and you cannot specify static properties and functions for the class.

Note: Starting with SpiderMonkey 1.8, the prototype and constructor are set up with stub getter and setter operations instead of class operations.

If you provide a constructor for the class, then you should also pass an object to parent_proto. JS_InitClass uses parent_proto to build a prototype object for the class. The prototype object inherits properties and methods from the parent_proto object you provide.

After building the constructor and prototype, JS_InitClass adds properties and methods. Ordinary properties and methods are added to the prototype. Static properties and methods are added to the constructor.  The properties are defined as though by calling JS_DefineProperties, and the methods as though by calling JS_DefineFunctions.

Note: By default JS_InitClass creates a prototype object but does not invoke the constructor (JSClass.construct) on it. However, the prototype object will eventually be finalized (JSClass.finalize). This inconsistency can cause problems; for example, if the finalizer calls JS_GetPrivate(), expecting that the constructor called JS_SetPrivate(), it may find that the private data is NULL. The JSCLASS_CONSTRUCT_PROTOTYPE flag is one way to avoid this inconsistency.

Warning: If the class is a JSExtendedClass, make sure that the additional reserved fields at the end of the JSExtendedClass are NULL. JSExtendedClass structs should usually be global, and in this case the compiler automatically initializes these fields to NULL. (This is a feature of the C and C++ languages.) Otherwise, use memset.

See Also

{{ LXRSearch("ident", "i", "JS_InitClass") }}

JS_GetClass, JS_InstanceOf

Revision Source

<p>Make a <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass" title="en/JSClass">JSClass</a></code> accessible to JavaScript code by creating its prototype, constructor, properties, and functions.</p>
<h2 name="Syntax">Syntax</h2>
<pre class="eval"><a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a> * <strong>JS_InitClass</strong>(<a href="/en/SpiderMonkey/JSAPI_Reference/JSRuntime" title="en/JSRuntime">JSContext</a> *cx, <a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a> *obj,
    <a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a> *parent_proto, <a href="/en/SpiderMonkey/JSAPI_Reference/JSClass" title="en/JSClass">JSClass</a> *clasp,
    <a href="/en/SpiderMonkey/JSAPI_Reference/JSNative" title="en/JSNative">JSNative</a> constructor, <a href="/en/SpiderMonkey/JSAPI_Reference/jsint" title="en/jsint">uintN</a> nargs,
    <a href="/en/SpiderMonkey/JSAPI_Reference/JSPropertySpec" title="en/JSPropertySpec">JSPropertySpec</a> *ps, <a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a> *fs,
    <a href="/en/SpiderMonkey/JSAPI_Reference/JSPropertySpec" title="en/JSPropertySpec">JSPropertySpec</a> *static_ps, <a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a> *static_fs);
</pre>
<table class="fullwidth-table"> <tbody> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> <tr> <td><code>cx</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSRuntime" title="en/JSRuntime">JSContext</a> *</code></td> <td>Pointer to a JS context from which to derive runtime information. {{ Jsapi-requires-request() }}</td> </tr> <tr> <td><code>obj</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a> *</code></td> <td>Pointer to the "globals" object to use for initializing the class. This must not be <code>NULL</code>. Once <code>JS_InitClass</code> creates the new class's constructor, it stores the constructor as a property in this object. So, for example, if this object is <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetGlobalObject" title="en/JS_GetGlobalObject">JS_GetGlobalObject</a>(cx)</code>, then JavaScript code will be able to see the new class as a global name.</td> </tr> <tr> <td><code>parent_proto</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a> *</code></td> <td>Pointer to an object to be used as a prototype. <code>JS_InitClass</code> always creates a new prototype object that serves as the <code>__proto__</code> for class instances; <code>parent_proto</code> becomes the <code>__proto__</code> of that prototype object.</td> </tr> <tr> <td><code>clasp</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass" title="en/JSClass">JSClass</a> *</code></td> <td>Pointer to the class structure to initialize. This structure defines the class for use by other API functions.</td> </tr> <tr> <td><code>constructor</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSNative" title="en/JSNative">JSNative</a></code></td> <td>The constructor for the class. Its scope matches that of the <code>obj</code> argument. If <code>constructor</code> is <code>NULL</code>, then <code>static_ps</code> and <code>static_fs</code> must also be <code>NULL</code>.</td> </tr> <tr> <td><code>nargs</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/jsint" title="en/jsint">uintN</a></code></td> <td>Number of arguments for the constructor.</td> </tr> <tr> <td><code>ps</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSPropertySpec" title="en/JSPropertySpec">JSPropertySpec</a> *</code></td> <td>Either <code>NULL</code> or a pointer to an array of <code>JSPropertySpec</code>s, terminated by the null <code>JSPropertySpec</code>, which can be written <code>{0, 0, 0, 0, 0}</code>. These properties, if any, are added to the class's new prototype object. All instances of the new class will inherit these properties via the prototype chain.</td> </tr> <tr> <td><code>fs</code></td> <td><code><a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a> *</code></td> <td>Either <code>NULL</code> or a pointer to an array of <code>JSFunctionSpec</code>s, terminated by <code><a href="/En/SpiderMonkey/JSAPI_Reference/JS_FS" title="en/JS_FS_END">JS_FS_END</a></code>. These functions, if any, are added to the class's new prototype object. All instances of the new class will inherit these methods via the prototype chain. (This is the JavaScript equivalent of public, non-static methods in C++ or Java.)</td> </tr> <tr> <td><code>static_ps</code></td> <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JSPropertySpec" title="en/JSPropertySpec">JSPropertySpec</a> *</code></td> <td>Either <code>NULL</code> or a pointer to an array of <code>JSPropertySpec</code>s, terminated by the null <code>JSPropertySpec</code>. These properties, if any, are added to the new class's constructor. (This is the nearest JavaScript equivalent of public static member variables in C++ or public static fields in Java.)</td> </tr> <tr> <td><code>static_fs</code></td> <td><code><a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a> *</code></td> <td>Either <code>NULL</code> or a pointer to an array of <code>JSFunctionSpec</code>s, terminated by <code><a href="/En/SpiderMonkey/JSAPI_Reference/JS_FS" title="en/JS_FS_END">JS_FS_END</a></code>. These functions, if any, are added to the new class's constructor. (This is the JavaScript equivalent of public static methods in C++ or Java.)</td> </tr> </tbody>
</table>
<h2 name="Description">Description</h2>
<p><strong><code>JS_InitClass</code></strong> initializes a <code>JSClass</code> and (optionally) makes it visible to JavaScript code.</p>
<p>This is one way to create <code>JSObject</code>s whose properties and methods are implemented in native C/C++. If you need a native function but you don't need to support instances or inheritance, <code>JS_InitClass</code> might be overkill. <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunction" title="en/JS_DefineFunction">JS_DefineFunction</a></code> is simpler.</p>
<p>A JSAPI class consists of a <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass" title="en/JSClass">JSClass</a></code> structure, a constructor, a prototype object, and properties and functions. The <code>JSClass</code> is an internal data structure that is not exposed outside the JavaScript engine. It specifies the name of the class, its flags, and its property access functions. These include native C functions for instance finalization, adding and deleting properties, getting and setting property values, and enumerating, converting, and resolving properties. The JSAPI provides reasonable default behavior for all of these; ordinarily you don't want to overload any of them.</p>
<p>After a successful call to <code>JS_InitClass</code>, JavaScript code can see and manipulate the class's constructor and prototype just as if it were an ordinary JavaScript function with a <code>prototype</code> property. JavaScript code can create new instances using the <code>new</code> keyword. Classes can have methods and properties that are present on all instances. They can also have methods and properties that are only present on the constructor; these are called "static methods" and "static properties" because they serve the same purpose and use the same syntax as static methods and fields in Java.</p>
<p>On success, <code>JS_InitClass</code> returns a pointer to a JS object that is the prototype for the newly initialized class. If <code>JS_InitClass</code> fails, it returns <code>NULL</code>.</p>
<p>The constructor for the class is built in the same context as <code>cx</code>, and in the same scope as <code>obj</code>. If you pass <code>NULL</code> as the <code>constructor</code> parameter, then a constructor is not built, and you cannot specify static properties and functions for the class.</p>
<div class="note"><strong>Note:</strong> Starting with SpiderMonkey 1.8, the prototype and constructor are set up with stub getter and setter operations instead of class operations.</div>
<p>If you provide a constructor for the class, then you should also pass an object to <code>parent_proto</code>. <code>JS_InitClass</code> uses <code>parent_proto</code> to build a prototype object for the class. The prototype object inherits properties and methods from the <code>parent_proto</code> object you provide.</p>
<p>After building the constructor and prototype, <code>JS_InitClass</code> adds properties and methods. Ordinary properties and methods are added to the prototype. Static properties and methods are added to the constructor.  The properties are defined as though by calling <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineProperties" title="En/SpiderMonkey/JSAPI Reference/JS DefineProperties"><code>JS_DefineProperties</code></a>, and the methods as though by calling <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunctions" title="En/SpiderMonkey/JSAPI Reference/JS DefineFunctions"><code>JS_DefineFunctions</code></a>.</p>
<div class="note"><strong>Note:</strong> By default <code>JS_InitClass</code> creates a prototype object but does not invoke the constructor (<code><a href="/en/JSClass.construct" title="en/JSClass.construct">JSClass.construct</a></code>) on it. However, the prototype object will eventually be finalized (<code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass.finalize" title="en/JSClass.finalize">JSClass.finalize</a></code>). This inconsistency can cause problems; for example, if the finalizer calls <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPrivate" title="en/JS_GetPrivate">JS_GetPrivate</a>()</code>, expecting that the constructor called <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPrivate" title="en/JS_SetPrivate">JS_SetPrivate</a>()</code>, it may find that the private data is <code>NULL</code>. The <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass.flags" title="en/JSClass.flags">JSCLASS_CONSTRUCT_PROTOTYPE</a></code> flag is one way to avoid this inconsistency.</div>
<div class="warning">
<p><strong>Warning:</strong> If the class is a <a href="/en/SpiderMonkey/JSAPI_Reference/JSExtendedClass" title="en/SpiderMonkey/JSAPI_Reference/JSExtendedClass"><code>JSExtendedClass</code></a>, make sure that the additional reserved fields at the end of the <code>JSExtendedClass</code> are <code>NULL</code>. <code>JSExtendedClass</code> structs should usually be global, and in this case the compiler automatically initializes these fields to <code>NULL</code>. (This is a feature of the C and C++ languages.) Otherwise, use <code>memset</code>.</p>
</div>
<h2 name="See_Also">See Also</h2>
<p>{{ LXRSearch("ident", "i", "JS_InitClass") }}</p>
<p><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GET_CLASS" title="en/JS_GET_CLASS">JS_GetClass</a>, <a href="/en/SpiderMonkey/JSAPI_Reference/JS_InstanceOf" title="en/JS_InstanceOf">JS_InstanceOf</a></p>
Revert to this revision