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

相關文章
相關標籤/搜索