JS::Value 编辑

JS::Value is the type of JavaScript values in the JSAPI.

A C++ variable of type JS::Value represents a value in JavaScript: a string, number, object (including arrays and functions), boolean, symbol, null, or undefined.

JS::Value is a class whose internal structure is an implementation detail. Embeddings should not rely on observed representation details or upon the size of JS::Value.

The data in a JS::Value can be accessed using these member functions:

JS typeJS::Value type testsConstructorAccessorsMutators
nullval.isNull()JS::NullValue()N/Aval.setNull()
undefinedval.isUndefined()JS::UndefinedValue()N/Aval.setUndefined()
booleanval.isBoolean(), val.isTrue(), val.isFalse()JS::BooleanValue(bool), JS::TrueValue(), JS::FalseValue()val.toBoolean()val.setBoolean(bool)
numberval.isInt32(), val.isDouble(), val.isNumber()JS::NumberValue(any number type), JS::Int32Value(int32_t), JS::DoubleValue(double), JS::Float32Value(float)val.toInt32(), val.toDouble(), val.toNumber()val.setInt32(int32_t), val.setNumber(uint32_t), val.setNumber(double)
stringval.isString()JS::StringValue(JSString*)val.toString()val.setString(JSString *)
objectval.isObject()JS::ObjectValue(JSObject&), JS::ObjectOrNullValue(JSObject*)val.toObject()val.setObject(JSObject &)
symbolval.isSymbol()JS::SymbolValue(JS::Symbol*)val.toSymbol()val.setSymbol(JS::Symbol &)

Numbers are stored in a JS::Value either as a double or as an int32_t. The different representations are visible using the separate int32/double methods but do not affect observable semantics (ignoring performance). The number mutators attempt to use int32_t representation for compatible input values, returning true when int32 could be used and false when double representation was required. Any double value may be stored in a JS::Value, in one of these two representations. The only exception is that only a single NaN value can be represented. (Note that both -0 and +0 are allowed, and the latter may sometimes be stored using the int32_t representation.)

JS::Value further provides these methods combining various aspects of the above methods:

  • JS::ObjectOrNullValue(JSObject*) returns an object value corresponding to the given non-null pointer, or a null value if the pointer is null.
  • val.setObjectOrNull(JSObject *) sets the given value to the specified object, or to null if the pointer was null.
  • val.isObjectOrNull() returns true if the value is either an object or undefined.
  • Correspondingly, val.toObjectOrNull() returns a non-null JSObject * if the value is an object, and NULL if the value is null.
  • val.isPrimitive() returns true if the value is a primitive value -- that is, not an object. It is equivalent to !val.isObject().
  • val.isNullOrUndefined() returns true if the value is either null or undefined.
  • val.isGCThing() returns true if a JS value has a type that is subject to garbage collection.

The are two major issues to be aware of when using JS::Value.

JS::Value is not inherently type-safe
It is an error to call any accessor method on a value of a non-matching type: val.toInt32() must only be called if val.isInt32(), val.toString() must only be called if val.isString(), and so on.
In particular, note that it is an error to call val.toObject() when val.isNull(). The now-deprecated jsval methods allowed JSVAL_TO_OBJECT(val) when JSVAL_IS_NULL(val), but this was a source of constant bugs. val.toObject() is only permitted when val.isObject(). An assertion is thrown in the case that the type is not correct (val.isX() is called for each val.toX(), where X is the type).
It is highly recommended that you develop and test with an --enable-debug build to detect most JS::Value misuse. Debug builds will assert correct JSAPI use in many other instances as well.
JS::Value is subject to garbage collection
A JS::Value can refer to a string or object located in SpiderMonkey's garbage-collected heap.
The garbage collector is designed to automatically free unreachable memory. It is rather eager about its job. It's like a robot that goes around picking up everything that isn't nailed down and putting it in the trash. If an application has a JS::Value variable that refers to a JSObject, the garbage collector might not know you're using the JSObject. So it might free it, leaving a dangling pointer. The solution is to tell SpiderMonkey that you're using the object, then tell it again when you're done.
In short, every JS::Value must be rooted or your program will randomly crash. In some places, SpiderMonkey provides already-rooted JS::Values which you can use for variables. See SpiderMonkey GC Rooting Guide.

The jsval typedef for JS::Value

JS::Value was historically known in the JSAPI as jsval. SpiderMonkey 1.8.5 made jsval into a C struct and exposed it in C++ through the full-fledged JS::Value class. As of SpiderMonkey 17, jsval is a typedef of JS::Value, and SpiderMonkey is gradually transitioning to a new C++ JSAPI, at whose heart lies JS::Value.

jsval is deprecated; new code should use JS::Value. The old JSVAL_IS_* methods, JSVAL_* constants and *_TO_JSVAL methods, and JSVAL_TO_* methods are also deprecated; uses of each should be replaced with use of the corresponding val.is*(), *Value(), and val.to*() methods.

JS typejsval type testsjsval constants and constructorsjsval accessors
nullJSVAL_IS_NULL(v)JSVAL_NULL 
undefinedJSVAL_IS_VOID(v)JSVAL_VOID 
booleanJSVAL_IS_BOOLEAN(v)JSVAL_TRUE, JSVAL_FALSE, BOOLEAN_TO_JSVAL(b)JSVAL_TO_BOOLEAN(v)
numberJSVAL_IS_NUMBER(v), JSVAL_IS_INT(v), JSVAL_IS_DOUBLE(v)JSVAL_ZERO, JSVAL_ONE, INT_TO_JSVAL(i), DOUBLE_TO_JSVAL(d)JSVAL_TO_INT(v), JSVAL_TO_DOUBLE(v)
stringJSVAL_IS_STRING(v)STRING_TO_JSVAL(str)JSVAL_TO_STRING(v), JS_GetStringChars(str), JS_GetStringLength(str)
object!JSVAL_IS_PRIMITIVE(v)OBJECT_TO_JSVAL(obj)JSVAL_TO_OBJECT(v)


There was also a further method, JSVAL_IS_OBJECT(v), which did not what you would expect -- return true if the value was an object -- but rather returned true if the value was an object or if it was null. These confusing semantics led to this method being removed from the JSAPI in more recent releases, but older code might still use it. Uses of this method should be replaced with v.isObjectOrNull().

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

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

发布评论

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

词条统计

浏览:171 次

字数:13287

最后编辑:6年前

编辑次数:0 次

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