SpiderMonkey内的JS中只有一种数据类型,就是JS::Value。 (1)SpiderMonkey对JS数据类型的判断 我们看Mozilla在SpiderMonkey的JSAPI用户手册中怎么说的呢? https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Cookbook // JavaScript var v = computeSomeValue(); //dark-f: 表明v是ComputeSomeValue()得到的某种类型的变量 //dark-f:e.g. var v = add(3, 6); //(function add(a, b){return a+b;}) var isString = typeof v === "string"; //dark-f:如果上面的v是string的话, 则isString这个boolean型的值为true var isNumber = typeof v === "number"; //dark-f:如同上面解释,v是number型 var isNull = v === null; //dark-f:v是null型 var isBoolean = typeof v === "boolean"; //dark-f:v是boolean型 var isObject = typeof v === "object" && v !== null; //dark-f:v是object型 var isSymbol = typeof v === "symbol"; var isFunction = typeof v === "function"; var isUndefined = typeof v === "undefined"; 上面是JS脚本语言,那么SpiderMonkey用什么JSAPI来判断js数据类型呢?同样看上面的手册 /* JSAPI */ JS::RootedValue v(cx, ComputeSomeValue()); //dark-f:表明v是由ComputeSomeValue()得到的 //------------------------ bool isString = v.isString(); bool isNumber = v.isNumber(); bool isInt32 = v.isInt32(); // NOTE: internal representation, not numeric value bool isNull = v.isNull(); bool isBoolean = v.isBoolean(); bool isObject = v.isObject(); // NOTE: not broken like typeof === "object" is :-) bool isSymbol = v.isSymbol(); bool isFunction = v.isObject() && JS::IsCallable(&v.toObject()); bool isUndefined = v.isUndefined(); SpiderMonkey提供了这样一些JSAPI来判断JS数据类型: . isString(); . isNumber(); . isInt32(); . isNull(); . isBoolean(); . isObject(); . isSymbol(); . JS::IsCallable(&v.toObject()); SpiderMonkey还提供了这样一些JSAPI来设定JS数据:(同样看上面的手册) 如果JS脚本是下面这样的: // JavaScript var v; v = 0; v = 0.5; v = someString; v = null; v = undefined; v = false; v = {}; v = new Symbol(someString); 那么在SpiderMonkey里,就可以利用这样一些JSAPI做到: /* JSAPI */ JS::RootedValue v(cx); JS::RootedString someString(cx, JS_NewStringCopyZ(cx, "my string")); JS::RootedObject obj(cx, JS_NewPlainObject(cx)); JS::RootedSymbol symbol(cx, JS::NewSymbol(cx, someString)); v.setInt32(0); // or: v = JS::Int32Value(0); v.setDouble(0.5); // or: v = JS::DoubleValue(0.5); v.setString(someString); // or: v = JS::StringValue(someString); v.setNull(); // or: v = JS::NullValue(); v.setUndefined(); // or: v = JS::UndefinedValue(); v.setBoolean(false); // or: v = JS::BooleanValue(false); v.setObject(*obj); // or: v = JS::ObjectValue(*obj); v.setSymbol(symbol); // or: v = JS::SymbolValue(symbol); v.setNaN(); // { setDouble(JS::GenericNaN()); } v.setMagic(JSWhyMagic why); v.setObjectOrNull(JSObject* arg); 也即,SpiderMonkey有如下的JSAPI来设定JS::Value的数值: . setInt32(); . setDouble(); . setString(); . setNull(); . setUndefined(); . setBoolean(); (2)SpiderMonkey对数据类型的转换 那么怎么让JS中的数据,C/C++能看的明白呢?这就必须在这两种数据之间存在转换方法。 在SpiderMonkey60编译完成后的include目录下的js目录内有一个Value.h头文件,这里列出了各种转换JSAPI方法。 bool toBoolean() const { return value().toBoolean(); } double toNumber() const { return value().toNumber(); } int32_t toInt32() const { return value().toInt32(); } double toDouble() const { return value().toDouble(); } JSString* toString() const { return value().toString(); } JS::Symbol* toSymbol() const { return value().toSymbol(); } JSObject& toObject() const { return value().toObject(); } JSObject* toObjectOrNull() const { return value().toObjectOrNull(); } 例如:在c++里,如果有一个JS::Value变量rval,是int32型的,要把这个变量的值显示出来,可以这样: printf("The value is %d\n", rval.toInt32()); 在Mozilla的JSAPI参考中(地址如下) https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference The following functions convert JS values to various types. They can be safely applied to JS::Value of any type. They may return new objects. For example, JS_ValueToObject(cx, s) where s is a string creates a new String wrapper object. These functions may call JavaScript methods. For example, JS_ValueToString(cx, obj) may call obj.toString(). . JS::ToBoolean (Added in SpiderMonkey 17) . JS::ToUint16 (Added in SpiderMonkey 17) . JS::ToInt32 (Added in SpiderMonkey 17) . JS::ToUint32 (Added in SpiderMonkey 17) . JS::ToInt64 (Added in SpiderMonkey 17) . JS::ToUint64 (Added in SpiderMonkey 17) . JS::ToNumber (Added in SpiderMonkey 17) . JS::ToString (Added in SpiderMonkey 31) . JS::OrdinaryToPrimitive (Added in SpiderMonkey 38) . JS_ValueToConstructor . JS_ValueToFunction . JS_ValueToObject . JS_ValueToSource 它们的语法如下:(在js目录里的conversion.h这个头文件里)
bool JS::ToBoolean(JS::HandleValue v); bool JS::ToUint16(JSContext *cx, JS::HandleValue v, uint16_t *out); bool JS::ToInt32(JSContext *cx, JS::HandleValue v, int32_t *out); bool JS::ToUint32(JSContext *cx, JS::HandleValue v, uint32_t *out); bool JS::ToInt64(JSContext *cx, JS::HandleValue v, int64_t *out); bool JS::ToUint64(JSContext *cx, JS::HandleValue v, uint64_t *out); bool JS::ToNumber(JSContext *cx, JS::HandleValue v, double *out); #include "js/Conversions.h" // as of SpiderMonkey 38; previously in jsapi.h JSString* JS::ToString(JSContext *cx, JS::HandleValue v); /* * ES6 draft 20141224, 7.1.1, second algorithm. * * Most users shouldn't call this -- use JS::ToBoolean, ToNumber, or ToString * instead. This will typically only be called from custom convert hooks that * wish to fall back to the ES6 default conversion behavior shared by most * objects in JS, codified as OrdinaryToPrimitive. */ extern JS_PUBLIC_API bool OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue vp); 下面的JSAPI来自jsapi.h文件 /* Don't want to export data, so provide accessors for non-inline Values. */ JS::Value JS_GetNaNValue(JSContext* cx); JS::Value JS_GetNegativeInfinityValue(JSContext* cx); JS::Value JS_GetPositiveInfinityValue(JSContext* cx); JS::Value JS_GetEmptyStringValue(JSContext* cx); JSString* JS_GetEmptyString(JSContext* cx); bool JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp); JSFunction* JS_ValueToFunction(JSContext* cx, JS::HandleValue v); JSFunction* JS_ValueToConstructor(JSContext* cx, JS::HandleValue v); JSString* JS_ValueToSource(JSContext* cx, JS::Handle<JS::Value> v); bool JS_DoubleIsInt32(double d, int32_t* ip); JSType JS_TypeOfValue(JSContext* cx, JS::Handle<JS::Value> v); |
|
来自: Dark_f > 《JavaScript》