JSClass 编辑

A JSClass describes a class of JavaScript objects. A C/C++ program can use a JSClass with the JS_InitClass and JS_NewObject APIs to create objects that have custom methods and properties implemented in C/C++.

Syntax

struct JSClass {
    const char          *name;
    uint32_t            flags;

    /* Optional since SpiderMonkey 37 */
    JSPropertyOp        addProperty;
    JSDeletePropertyOp  delProperty;
    JSPropertyOp        getProperty;
    JSStrictPropertyOp  setProperty;
    JSEnumerateOp       enumerate;
    JSResolveOp         resolve;

    JSConvertOp         convert;      /* Obsolete since SpiderMonkey 44 */

    /* Optional since SpiderMonkey 25 */
    JSFinalizeOp        finalize;

    /* Optional */
    JSClassInternal     reserved0;    /* Obsolete since SpiderMonkey 13 */
    JSCheckAccessOp     checkAccess;  /* Obsolete since SpiderMonkey 29 */
    JSNative            call;
    JSHasInstanceOp     hasInstance;
    JSNative            construct;
    JSXDRObjectOp       xdrObject;    /* Obsolete since SpiderMonkey 13 */
    JSTraceOp           trace;        /* Added in SpiderMonkey 17 */

    JSClassInternal     reserved1;    /* Obsolete since SpiderMonkey 13 */
    void                *reserved[N]; /* sizeof 'reserved' depends on version */
};
NameTypeDescription
nameconst char *Class name
flagsuint32_tClass flags. This field is the bitwise OR of one or more of the JSCLASS_* constants described in JSClass.flags.
addPropertyJSPropertyOp

A hook called just after adding a new property. May modify the new property value.

Use NULL or JS_PropertyStub (SpiderMonkey 31 or older) for default behavior.

delPropertyJSDeletePropertyOp

A hook called when deleting a property. May veto.

Use NULL or JS_DeletePropertyStub (SpiderMonkey 31 or older) for default behavior.

getPropertyJSPropertyOp

A hook called when getting a property. This is the default getter for the class.

Use NULL or JS_PropertyStub (SpiderMonkey 31 or older) for default behavior.

setPropertyJSStrictPropertyOp

A hook called when setting a property. This is the default setter for the class. When a script creates a new property, this is called after addProperty.

Use NULL or JS_StrictPropertyStub (SpiderMonkey 31 or older) for default behavior.

enumerateJSEnumerateOp

Method for enumerating object properties.

Use NULL or JS_EnumerateStub (SpiderMonkey 31 or older) for default behavior.

Obsolete since JSAPI 37 The JSCLASS_NEW_ENUMERATE flag instructs SpiderMonkey to call this as a JSNewEnumerateOp.

resolveJSResolveOp

Hook for implementing lazy properties. See JSClass.resolve for details.

Use NULL or JS_ResolveStub (SpiderMonkey 31 or older) for default behavior.

Obsolete since JSAPI 36 The JSCLASS_NEW_RESOLVE flag instructs SpiderMonkey to call this as a JSNewResolveOp.

Obsolete since JSAPI 16The JSCLASS_NEW_RESOLVE_GETS_START flag further affects this hook.

convertJSConvertOp

This hook specifies how objects of this class are converted to a primitive value.  It implements the object's [[DefaultValue]] hook, which is invoked by JavaScript when the object must be converted to a string, number, or primitive value. Obsolete since JSAPI 44

Use NULL or JS_ConvertStub (SpiderMonkey 31 or older) for default behavior, which is equivalent to that defined by ECMAScript in §8.12.8.

finalizeJSFinalizeOp

The object finalizer hook. This is called at some point after the object becomes unreachable, and can be used to free any additional resources associated with the object.

If objects of this class do not need finalization, use NULL.

checkAccessJSCheckAccessOpOptional method for access checks. Implements JS_CheckAccess. If your application does not use the JSAPI's security features, use NULL. Obsolete since JSAPI 29
callJSNativeThis is called when a script calls an object as though it were a function: obj(). If objects of your class shouldn't be callable, use NULL. Most objects are not callable.
hasInstanceJSHasInstanceOpPointer to an optional hasInstance method for this object. If you do not provide a method for hasInstance, set this pointer to NULL.
constructJSNativeThis is called when a script uses an object as though it were a constructor: new obj().  If objects of your class shouldn't be callable this way, use NULL. Most custom objects are not intended to be used as constructors.
xdrObjectJSXDRObjectOpImplements object serialization. If you do not use JSXDR, set this pointer to NULL. Obsolete since JSAPI 13
traceJSTraceOp

The GC trace hook.

Description

Use JSClass to define a custom class of JavaScript objects. A JSClass has a name, flags, and several callback functions for advanced customization of object behavior.

Simple classes

A simple custom class does not require any special JSClass callbacks. Instead, all the native code is in JSPropertyOps (property getters and setters) and JSNatives or JSFastNatives (methods). The code for such a class is simple:

/* SpiderMonkey 38 */
static JSClass robot_class = {
    "Robot",  /* name */
    0         /* flags */
};

/* SpiderMonkey 31 or older */
static JSClass robot_class = {
    "Robot",  /* name */
    0,        /* flags */
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
    JSCLASS_NO_OPTIONAL_MEMBERS
};

To expose this class to scripts, and to attach methods and properties to it, use JS_InitClass.

Private data

Custom classes very often need to store private C/C++ data that should not be visible to scripts. To do this, use the JSCLASS_HAS_PRIVATE (JSCLASS_CONSTRUCT_PROTOTYPE wad removed) flags. Implement a JSNative constructor function that allocates this private data and stores it in the new object using JS_SetPrivate. Implement a JSClass.finalize callback that frees the private data. Each native getter, setter, or method can access the private data using JS_GetInstancePrivate.

When initializing the class, pass the JSNative constructor function to JS_InitClass.

(This example uses the C++ new and delete keywords, but the application can allocate the memory for private data however it likes. The JavaScript engine never touches the private data; it is for the application's use only.)

void
printer_finalize(JSContext *cx, JSObject *obj)
{
    MyPrinter *p = (MyPrinter *) JS_GetPrivate(cx, obj);
    delete p;
}

static JSClass printer_class = {
    "Printer",
    JSCLASS_HAS_PRIVATE,
    NULL, NULL, NULL, NULL,
    NULL, NULL, NULL, printer_finalize
};

/* SpiderMonkey 31 or older
 * static JSClass printer_class = {
 *     "Printer",
 *     JSCLASS_HAS_PRIVATE,
 *     JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
 *     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, printer_finalize,
 *     JSCLASS_NO_OPTIONAL_MEMBERS
 * };
 */

bool
printer_construct(JSContext *cx, unsigned argc, jsval *vp)
{
    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    JSObject *obj = JS_NewObjectForConstructor(cx, &printer_class, args);
    /* SpiderMonkey 31 or older
     * JSObject *obj = JS_NewObjectForConstructor(cx, &printer_class, vp);
     */
    if (!obj)
        return false;

    MyPrinter *p = new MyPrinter;
    if (p == NULL) {
        JS_ReportOutOfMemory(cx);
        return false;
    }
    JS_SetPrivate(cx, obj, p);

    args.rval().setObject(*obj);
    /* SpiderMonkey 31 or older
     * JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
     */
    return true;
}

{
  JS_InitClass(cx, global, JS::NULL(), &printer_class, printer_construct, 1,
               NULL, NULL, NULL, NULL);
}

See also

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:164 次

字数:19987

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文