JavaScriptCoreC语言API详细介绍

JavaScriptCore C API 详细解析git

JavaScriptCore介绍github

JavaScriptCore 是 JavaScript 引擎,一般会被叫作虚拟机,专门设计来解释和执行 JavaScript 代码,能够理解为一个浏览器的运行内核。api

JavaScriptCore Framework 是 iOS7 引入的新功能,其实就是基于 Webkit 中以 C/C++ 实现的 JavaScriptCore 的一个封装,大多数 iOS 比较熟悉的是它的 Objective-C API,能够用简介的方式 JS 与Native 通信,其实它还有C API的部分,虽然也是开源的,可是在查看源代码时只有较少的介绍,并且咱们知道 Objective-C API 只是 C API 接口的封装。本文主要介绍 C API 部分,帮助你们更好理解 JavaScriptCore Framework。数组

JavaScriptCore C API浏览器

JavaScriptCore C API 部分包含六个类 下面咱们详细解释每一个类的做用及用法函数

  • JSBase.h JavaScriptCore 的接口文件,这个类中 import 了其余的类,简单封装了其余的 C API。
  • JSContextRef.h JSContextRef 至关于 Objective-C 中的 JSContext,主要提供 JS 执行的上下文环境。
  • JSObjectRef.h JSObjectRef 至关于 Objective-C 中的 JSObject,它表明一个JavaScript对象,交互的核心放在都在这个类中实现。
  • JSStringRef.h 是 JavaScript 中基本的字符串表示形式。
  • JSStringRefCF.h 包含 CFString 便利的方法。
  • JSValueRef.h JSValueRef 至关于 Objective-C 中的 JSValue ,对应一个 JavaScript 的值,它是全部JavaScript值的基本类型

JSBase.h测试

定义了 JavaScriptCore 接口文件 ,主要提供了三个方法this

//检查JavaScript 字符串中的语法错误。
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef *exception);

//执行一段js语句
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef *exception);

//执行JavaScript GC  在JavaScript执行期间,通常不须要调用此函数; JavaScript 引擎将根据须要进行垃圾回收,在释放对上下文组的最后一个引用时,将自动销毁在上下文组中建立的JavaScript值。
void JSGarbageCollect(JSContextRef ctx);
复制代码

JSContextRef.hlua

主要提供 JS 执行所需全部资源和环境spa

//获取全局的 globalObject 对象,该对象将全局的 JavaScript 设置为跟对象,所以咱们能够将咱们本身的对象定义为 JavaScript 执行环境。
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);

// contextGroup 对象提供了虚拟机的功能 简单类比 JSVirtualMachine 可是须要本身管理内存。
JSContextGroupRef JSContextGetGroup(JSContextRef ctx);
JSContextGroupRef JSContextGroupCreate(void);
void JSContextGroupRelease(JSContextGroupRef group);
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group);

//globalContext对象是提供执行 js 的环境 简单类比 JSContext
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass);//crete
JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass);//CreateInGroup
void JSGlobalContextRelease(JSGlobalContextRef ctx);//relase
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx);//retain
复制代码

JSObjectRef.h

是一个 JavaScript 对象,主要提供了两部分API,一部分是建立 JS 对象,还有一部分是给建立的 JS 对象添加对应的 Callback。

Functions

// 建立 JavaScript 类 JSClassCreate JSClassRelease JSClassRetain
JSClassRef JSClassCreate(const JSClassDefinition *definition);

JSObjectMake //建立 JavaScript 对象
JSObjectMakeArray //建立数组
JSObjectMakeConstructor
JSObjectMakeDate 、
JSObjectMakeError
JSObjectMakeFunction
JSObjectMakeRegExp

//JavaScript 对象做为构造函数来调用
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);

//JavaScript 对象做为方法来调用
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);

JSObjectCopyPropertyNames //获取对象的全部可枚举属性
JSObjectDeleteProperty //从对象中删除属性

//对 JS 对象的 Private、Property、Prototype 操做
JSObjectGetPrivate JSObjectSetPrivate
JSObjectGetProperty JSObjectSetProperty
JSObjectGetPrototype JSObjectSetPrototype
JSObjectGetPropertyAtIndex JSObjectSetPropertyAtIndex

//对 JS 对象的属性名的操做
JSPropertyNameArrayRetain
JSPropertyNameArrayRelease
JSPropertyNameArrayGetNameAtIndex
JSPropertyNameArrayGetCount
JSPropertyNameAccumulatorAddName

//JS对象条件判断
JSObjectHasProperty //是否有属性
JSObjectIsFunction // 是不是一个方法
JSObjectIsConstructor // 是不是构造函数
复制代码

callBacks

在建立一个JS对象的同时,能够给该对象设置对应的callback,例如能够在先建立一个functionJSObjectMakeFunction,同时设置该方法被调用的callback JSObjectCallAsFunctionCallback最后调用该方法 JSObjectCallAsFunction此时callback设置的方法就会响应

上述全部建立对象的方法都有对应的callback能够设置,咱们能够灵活的使用这些方法

Type Alias JSObjectCallAsConstructorCallback //当该对象被座位构造函数调用是响应callback
typedef JSObjectRef (*JSObjectCallAsConstructorCallback)(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);

JSObjectCallAsFunctionCallback
typedef JSValueRef (*JSObjectCallAsFunctionCallback)(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);
复制代码

JSValueRef.h

一个 JavaScript 值,提供用Object-C的基础数据类型来建立 JS 的值,或者将JS 的值转变为OC的基础数据类型

//获取JavaScript值类型
JSValueGetType

//OC基础数据建立JS的值
JSValueCreateJSONString
JSValueMakeBoolean
JSValueMakeFromJSONString
JSValueMakeNull
JSValueMakeNumber
JSValueMakeString
JSValueMakeUndefined

//JS值转变为OC基础数据
JSValueToBoolean
JSValueToNumber
JSValueToObject
JSValueToStringCopy

//存储JSValue
JSValueProtect
JSValueUnprotect

//比较判断JavaScript值类型
JSValueIsBoolean
JSValueIsNull
JSValueIsNumber
JSValueIsObject
JSValueIsObjectOfClass
JSValueIsStrictEqual
JSValueIsString
JSValueIsUndefined
JSValueIsEqual
JSValueIsInstanceOfConstructor
复制代码

JSStringRef.h

JavaScript 对象中字符串对象,公开的api包括以下

JSStringCreateWithCharacters 
JSStringCreateWithUTF8CString
JSStringGetCharactersPtr
JSStringGetLength
JSStringGetMaximumUTF8CStringSize
JSStringGetUTF8CString
JSStringIsEqual
JSStringIsEqualToUTF8CString
JSStringRelease
JSStringRetain
复制代码

JSStringRefCF.h

CFString 与 JavaScript string 相互转化

CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string);
JSStringRef JSStringCreateWithCFString(CFStringRef string);
复制代码

测试Demo

上面介绍完整个JavaScriptCore C API部分,下面咱们经过一个demo来详细分析如何使用这些api

#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>

JSValueRef ObjectGetPropertyCallback(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef *exception){
     NSLog(@"ObjectGetPropertyCallback");
    return nil;
};

JSValueRef ObjectCallAsFunctionCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
     NSLog(@"ObjectCallAsFunctionCallback");
    return JSValueMakeUndefined(ctx);
}

void ObjectConstructorFinalize(JSObjectRef object) {
   NSLog(@"ObjectConstructorFinalize");
}

bool ObjectConstructorHasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception) {
    NSLog(@"ObjectConstructorHasInstance");
    return nil;
}

JSObjectRef ObjectCallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argc, const JSValueRef argv[], JSValueRef* exception) {
     NSLog(@"ObjectCallAsConstructor");
    return nil;
}

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    JSContextGroupRef contextGroup = JSContextGroupCreate();
    JSGlobalContextRef globalContext = JSGlobalContextCreateInGroup(contextGroup, nil);
    JSObjectRef globalObject = JSContextGetGlobalObject(globalContext);
    
    JSClassDefinition constructorClassDef = kJSClassDefinitionEmpty;
    constructorClassDef.getProperty = ObjectGetPropertyCallback;
    constructorClassDef.callAsFunction = ObjectCallAsFunctionCallback;
    constructorClassDef.callAsConstructor = ObjectCallAsConstructor;
    constructorClassDef.hasInstance = ObjectConstructorHasInstance;
    constructorClassDef.finalize = ObjectConstructorFinalize;
  
    JSClassRef loaderClass = JSClassCreate(&constructorClassDef);
    
    JSObjectRef loader = JSObjectMake(globalContext, loaderClass, (__bridge void *)(self.view));
    JSStringRef logFunctionName = JSStringCreateWithUTF8CString("log");
    JSObjectSetProperty(globalContext, globalObject, logFunctionName, loader, kJSPropertyAttributeNone, nil);
    
    JSStringRef logCallStatement = JSStringCreateWithUTF8CString("log()");
    
    JSEvaluateScript(globalContext, logCallStatement, nil, nil, 1,nil);
    
    /* memory management code to prevent memory leaks */
    
    JSGlobalContextRelease(globalContext);
    JSContextGroupRelease(contextGroup);
    JSStringRelease(logFunctionName);
    JSStringRelease(logCallStatement);
}
复制代码

执行结果

2018-07-02 20:29:47.485072+0800 ObjectCallAsFunctionCallback

2018-07-02 20:29:47.485290+0800 ObjectGetPropertyCallback

2018-07-02 20:29:47.489448+0800 ObjectConstructorFinalize

下面咱们详细分析这段代码

contextGroup 是JS执行的虚拟机,后续全部的一切基于它来进行

globalContext 是JavaScript的执行环境,第一个参数数虚拟机,第二个参数是nil,是使用默认的类来做为跟对象

globalObject 获取全局的 globalObject 对象

constructorClassDef 定义一个 JavaScript 类,同时设置该类的特殊事件的callback 如getProperty、callAsFunction

loaderClass 建立一个 JavaScript 类

loader  经过 JavaScript 类 建立一个 JavaScript 对象

JSObjectSetProperty  给全局的 globalObject 对象设置关联信息 @“log”

JSEvaluateScript 执行log方法

JSObjectSetProperty  给全局的 globalObject 对象设置class 

JSEvaluateScript 调用 class 的 方法
复制代码

github地址: https://github.com/Richard-zhang-iOS/JavaScriptCore-C-Demo 原创不易,欢迎star

相关文章
相关标签/搜索