SpiderMonkey JSAPI Code Snippets
Define Primitive types
Primitive types
javascript
var v;
v = 0;
v = 0.5;
v = someString;
v = null;
v = undefined;
v = false;
C++
JS::RootedValue v(cx);
JS::RootedString someString(cx, ...);
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);
Check Primitive Types
Primitive Types
javascript
var v = computeSomeValue();
var isString = typeof v === "string";
var isNumber = typeof v === "number";
var isNull = v === null;
var isBoolean = typeof v === "boolean";
var isObject = typeof v === "object" && v !== null;
C++
JS::RootedValue v(cx, ComputeSomeValue());
bool isString = v.isString();
bool isNumber = v.isNumber();
bool isInt32 = v.isInt32();
bool isNull = v.isNull();
bool isBoolean = v.isBoolean();
bool isObject = v.isObject();
Define Function
Function
javascript
function justForFun() {
return null;
}
C++
bool justForFun(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setNull();
return true;
}
Creat Array Object
Array Object
javascript
var x = []; // or "x = Array()", or "x = new Array"
C++
JS::RootedObject x(cx, JS_NewArrayObject(cx, 0));
if (!x)
return false;
Creat Plain Object
Plain Object
javascript
var x = {}; // or "x = Object()", or "x = new Object"
C++
JS::RootedObject x(cx, JS_NewPlainObject(cx));
// or JS_NewObject(cx, JS::NullPtr(), JS::NullPtr(), JS::NullPtr());
if (!x)
return false;
New Object
Object
javascript
var person = new Person("Dave", 24);
C++
/* Step 1 - Get the value of Person and check that it is an object. */
JS::RootedValue constructor_val(cx);
if (!JS_GetProperty(cx, JS_GetGlobalObject(cx), "Person", &constructor_val))
return false;
if (!constructor_val.isObject()) {
JS_ReportError(cx, "Person is not a constructor");
return false;
}
JS::RootedObject constructor(cx, &constructor_val.toObject());
/* Step 2 - Set up the arguments. */
JS::RootedString name_str(cx, JS_NewStringCopyZ(cx, "Dave"));
if (!name_str)
return false;
JS::AutoValueArray<2> args(cx);
args[0].setString(name_str);
args[1].setInt32(24);
/* Step 3 - Call |new Person(...args)|, passing the arguments. */
JS::RootedObject obj(cx, JS_New(cx, constructor, args));
if (!obj)
return false;
Call Global Function
Function
javascript
var r = foo(); // where f is a global function
C++
JS::RootedValue r(cx);
if (!JS_CallFunctionName(cx, JS_GetGlobalObject(cx), "foo", 0, NULL, &r))
return false;
Return value in Function
Function
javascript
function justForFun() {
return 23;
// return 3.14159;
}
C++
bool justForFun(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setInt32(23);
// args.rval().setDouble(3.14159);
return true;
}
Get Object
propert
Object
propertjavascript
var x = y.myprop;
C++
JS::RootedValue x(cx);
assert(y.isObject());
JS::RootedObject yobj(cx, &y.toObject());
if (!JS_GetProperty(cx, yobj, "myprop", &x))
return false;
Set Object
property
Object
propertyjavascipt
y.myprop = x;
C++
assert(y.isObject());
JS::RootedObject yobj(cx, &y.toObject());
if (!JS_SetProperty(cx, yobj, "myprop", &x))
return false;
Check Object
property
Object
propertyjavascript
if ("myprop" in y) {
// then do something
}
C++
bool found;
assert(y.isObject());
JS::RootedObject yobj(cx, &y.toObject());
if (!JS_HasProperty(cx, yobj, "myprop", &found))
return false;
if (found) {
// then do something
}
Register namespace
(object
)
namespace
(object
)C++
Cocos
JS::RootedValue nsval(cx);
JS::RootedObject ns(cx);
if (nsval == JSVAL_VOID /* nsval.isNullOrUndefined() */) {
ns.set(JS_NewObject(cx, NULL, JS::NullPtr(), JS::NullPtr()));
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, global, "cc", nsval);
}
javascript
Binding
cc.log(cc); // console: [object Object]
Register Global Functions
Functions
C++
Cocos
JS_DefineFunction(cx, global, "require", func_impl_in_cpp, 1, JSPROP_PERMANENT);
javascript
require("path/to/fileA.js");
require("path/to/fileB.js");
require("path/to/fileC.js");
Complie RootedScript
from .jsc
RootedScript
from .jsc
C++
Cocos
JS::RootedScript script(cx);
JS::RootedObject obj(cx, global);
JSAutoCompartment ac(cx, global);
Data data = getDataFromFile("xxx.jsc");
script = JS_DecodeScript(cx, data.getBytes(), static_cast<uint32_t>(data.getSize()), nullptr);
Complie RootedScript
from .js
RootedScript
from .js
C++
Cocos
JS::RootedScript script(cx);
JS::RootedObject obj(cx, global);
JSAutoCompartment ac(cx, global);
std::string fullPath = fullPathForFilename("xxx.js");
JS::CompileOptions op(cx);
op.setUTF8(true);
op.setFileAndLine(fullPath.c_str(), 1);
JS::Compile(cx, obj, op, fullPath.c_str(), &script);
Run Complied RootedScript
RootedScript
C++
Cocos
JS::RootedScript script(cx);
JS::RootedValue rval(cx);
JSAutoCompartment ac(cx, global);
JS_ExecuteScript(cx, global, script, &rval);
Get JSObject
proto name
JSObject
proto nameC++
JS::RootedObject jsrTargetObject(cx, jsObject);
JS::RootedObject proto(cx);
if (JS_GetPrototype(cx, jsrTargetObject, &proto)) {
CCLOG("%s", JS_GetClass(proto)->name);
}
Iterate JSObject
properties
JSObject
propertiesC++
JS::RootedObject jsrTargetObject(cx, jsObject);
JS::RootedObject jsrPropertyIterator(
cx, JS_NewPropertyIterator(cx, jsrTargetObject)
);
while (true) {
JS::RootedId jsrIdp(cx);
JS::RootedValue jsrKey(cx);
// iter
if (!JS_NextProperty(cx, jsrPropertyIterator, jsrIdp.address()) ||
!JS_IdToValue(cx, jsrIdp, &jsrKey)) {
CCLOG("JS_NextProperty || JS_IdToValue failed !");
break;
}
if (jsrKey.isNullOrUndefined()) {
CCLOG("End");
break;
}
// get property
if (jsrKey.isInt32()) {
JS::RootedValue value(cx);
JS_GetPropertyById(cx, jsrTargetObject, jsrIdp, &value);
CCLOG("Key: %d - value: %d", jsrKey.toInt32(), value.toInt32());
}
else if (jsrKey.isString()) {
// ...
}
// ...
}
Iterate JS::RootedValue
Array
JS::RootedValue
ArrayC++
if (JS_IsArrayObject(cx, value)) {
JS::RootedObject jsrObjectTemp(cx, &value.toObject());
uint32_t length;
JS_GetArrayLength(cx, jsrObjectTemp, &length);
for( uint32_t i = 0; i < length; i ++) {
JS::RootedValue valarg(cx);
JS_GetElement(cx, jsrObjectTemp, i, &valarg);
if (valarg.isInt32()) {
CCLOG("value: %d", valarg.toInt32());
}
else if (valarg.isDouble()) {
// ...
}
// ...
}
}
Last updated
Was this helpful?