转载请注明出处:http://blog.youkuaiyun.com/awebkit
如何扩展一个函数
JSGlobalContextRef context = JSGlobalContextCreateInGroup(NULL, NULL);
JSObjectRef globalObject = JSContextGetGlobalObject(context);
JSStringRef printIString = JSStringCreateWithUTF8CString("print");
JSObjectSetProperty(context, globalObject, printIString, JSObjectMakeFunctionWithCallback(context, printIString, print), kJSPropertyAttributeNone, NULL);
JSStringRelease(printIString);
首先创建 JavaScript 执行环境 JSGlobalContextRef 。关于 JSGlobalContextRef 和 JSContextRef ,可以认为他们是一样的。定义如下。
/*! @typedef JSContextRef A JavaScript execution context. Holds the global object and other execution state. */
typedef const struct OpaqueJSContext* JSContextRef;
/*! @typedef JSGlobalContextRef A global JavaScript execution context. A JSGlobalContext is a JSContext. */
typedef struct OpaqueJSContext* JSGlobalContextRef;
别去找 OpaqueJSContext 的定义了,没有!当时我搜了好久。。。只要知道这是指针即可。
/*!
@function
@abstract Sets a property on an object.
@param ctx The execution context to use.
@param object The JSObject whose property you want to set.
@param propertyName A JSString containing the property's name.
@param value A JSValue to use as the property's value.
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
*/
JS_EXPORT void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);
所以,这句话的意思就是,在全局对象上加一个属性,属性名叫 print ,值对应 JSObjectMakeFunctionWithCallback(context, printIString, print) 。这也是一个关键函数。
/*!
@function
@abstract Convenience method for creating a JavaScript function with a given callback as its implementation.
@param ctx The execution context to use.
@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function.
@param callAsFunction The JSObjectCallAsFunctionCallback to invoke when the function is called.
@result A JSObject that is a function. The object's prototype will be the default function prototype.
*/
JS_EXPORT JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction);
JSObjectCallAsFunctionCallback 的定义
/*!
@typedef JSObjectCallAsFunctionCallback
@abstract The callback invoked when an object is called as a function.
@param ctx The execution context to use.
@param function A JSObject that is the function being called.
@param thisObject A JSObject that is the 'this' variable in the function's scope.
@param argumentCount An integer count of the number of arguments in arguments.
@param arguments A JSValue array of the arguments passed to the function.
@param exception A pointer to a JSValueRef in which to return an exception, if any.
@result A JSValue that is the function's return value.
@discussion If you named your function CallAsFunction, you would declare it like this:
JSValueRef CallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
If your callback were invoked by the JavaScript expression 'myObject.myFunction()', function would be set to myFunction, and thisObject would be set to myObject.
If this callback is NULL, calling your object as a function will throw an exception.
*/
typedef JSValueRef
(*JSObjectCallAsFunctionCallback) (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
我们再回到开头,print 对应的 JSObjectCallAsFunctionCallback 是如下定义的,这是 c++ 和 JavaScript 对应的函数。(哦,下面的代码忘记释放JSStringRef 了)
static JSValueRef print(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
UNUSED_PARAM(object);
UNUSED_PARAM(thisObject);
if (argumentCount > 0) {
JSStringRef string = JSValueToStringCopy(context, arguments[0], exception);
size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
char stringUTF8[numChars];
JSStringGetUTF8CString(string, stringUTF8, numChars);
printf("%s\n", stringUTF8);
}
return JSValueMakeUndefined(context);
}
总结一下,创建 context ,获取全局对象,设置全局对象新的属性和值。这样就把一个函数加入到了 JavaScript Engine
如何扩展一个对象
JSStringRef node = JSStringCreateWithUTF8CString("Node");
JSObjectSetProperty(context, globalObject, node, JSObjectMakeConstructor(context, JSNode_class(context), JSNode_construct), kJSPropertyAttributeNone, NULL);
JSStringRelease(node);
JSObjectMakeConstructor 的定义如下
/*!
@function
@abstract Convenience method for creating a JavaScript constructor.
@param ctx The execution context to use.
@param jsClass A JSClass that is the class your constructor will assign to the objects its constructs. jsClass will be used to set the constructor's .prototype property, and to evaluate 'instanceof' expressions. Pass NULL to use the default object class.
@param callAsConstructor A JSObjectCallAsConstructorCallback to invoke when your constructor is used in a 'new' expression. Pass NULL to use the default object constructor.
@result A JSObject that is a constructor. The object's prototype will be the default object prototype.
@discussion The default object constructor takes no arguments and constructs an object of class jsClass with no private data.
*/
JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);
这里, JSClassRef 要复杂很多。如果对插件的 NPAPI 接口熟悉,就知道这个也是一些函数指针需要初始化。我们还回到例子中,看例子里面都实现了哪些函数
JSClassRef JSNode_class(JSContextRef context)
{
UNUSED_PARAM(context);
static JSClassRef jsClass;
if (!jsClass) {
JSClassDefinition definition = kJSClassDefinitionEmpty;
definition.staticValues = JSNode_staticValues;
definition.staticFunctions = JSNode_staticFunctions;
definition.initialize = JSNode_initialize;
definition.finalize = JSNode_finalize;
jsClass = JSClassCreate(&definition);
}
return jsClass;
}
这里只实现了 JSClassRef 的 staticValues(静态属性) staticFunctions(静态方法) initialize finalize。 initialize 和 finalize 相当于构造函数和析构函数。
static JSStaticValue JSNode_staticValues[] = {
{ "nodeType", JSNode_getNodeType, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "childNodes", JSNode_getChildNodes, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "firstChild", JSNode_getFirstChild, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ 0, 0, 0, 0 }
};
static JSStaticFunction JSNode_staticFunctions[] = {
{ "appendChild", JSNode_appendChild, kJSPropertyAttributeDontDelete },
{ "removeChild", JSNode_removeChild, kJSPropertyAttributeDontDelete },
{ "replaceChild", JSNode_replaceChild, kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
好了,对象的绑定大概就这么多吧
284



被折叠的 条评论
为什么被折叠?



