您的位置:首页 > Web前端 > JavaScript

JavaScriptCore学习总结

2017-01-23 11:05 369 查看
JavaScriptCore可以完成OC中执行js语句,在oc中访问js代码中定义的全局变量(包括方法),也可以使得oc中定义的属性、方法得以在js代码中被调用。

整个JavaScriptCore framework包含的头文件如下,其中开放的接口可以分为两部分,一部分是C接口,一部分是OC接口。如果需要使用OC接口,那就引用JavaScriptCore.h,如果只需要使用C接口,那就引用JavaScript.h就好了



没错,也就是说在JavaScript.h中出现的几个头文件就是C接口部分。而OC部分是对C接口进行了进一步的封装,看起来更加面向对象,但是两者思想都是一样的。使用的时候选哪个,就看需要啦。

总体思路

用JSContext来表示JS代码执行的上下文,通过它可以执行js代码,可以读取js中的变量,也可以向js中添加变量,这里说的都是全局变量,用JSValue来表示。而所谓的全局变量就是作用域是全局的,但实际上只是在一定的范围内是全局的,这个范围用JSVirtualMachine.h来标识。JSContext需要和JSVirtualMachine关联起来,然后通过这个JSContext执行的js代码、添加的变量等等都处于同一个范围中,换言之,和另一个JSVirtualMachine关联的JSContext所执行的代码、添加的变量则属于另外一个范围,这两个范围之间是互不影响的。

上面的思想中,OC接口和C接口只有一点点差别,就是JSVirtualMachine只存在于OC接口中,而在C接口中相同的概念使用ContextGroup来表示。

Javascriptcore OC语言接口总结

JSContext就是JS上下文

1.每一个JSContext实例都和一个JavaScript virtual machine关联,可以说JSContext实例需要由JS虚拟机创建。可以这样初始化一个JSContext:

- (instancetype)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;


2.JSContext对该上下文中所有的全局变量保持强引用。可以像给字典插入键值对一样向JS上下文中插入或读取全局变量:

JSContext *context;
JSValue *v = context[@"X"]; // 获取JS中的变量X
context[@"Y"] = v;//访问JS中的变量Y并赋值,也可以是在JS中新建一个Y变量


3.在该上下文中执行javaScript语句:返回这段语句中产生的最后一个值

- (JSValue *)evaluateScript:(NSString *)script;
- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL NS_AVAILABLE(10_10, 8_0);


上面带上一个url纯粹是方便debug,对js执行无影响

4.可以和C语言接口中的JSContextRef结构体进行相互转换:

JSContextRef转JSContext:

+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)jsGlobalContextRef;


获取JSContext对应的JSContextRef:

@property (readonly) JSGlobalContextRef JSGlobalContextRef;


JSValue就表示一个JS中的一个值

1.每个JSValue实例都和一个JSContext实例相关联,也间接和一个JavaScript virtual machine关联。针对一个JSValue的方法执行中如果产生了另一个JSValue实例,那么这两个JSValue实例处在同一个上下文中,也就是说和同一个JSContext关联。

2.将oc类型转化成JSValue,或者说创建一个JSValue实例的方法:

+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;
+ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context;
+ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context;
+ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context;
+ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context;
+ (JSValue *)valueWithNewObjectInContext:(JSContext *)context;
+ (JSValue *)valueWithNewArrayInContext:(JSContext *)context;
+ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context;
+ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context;
+ (JSValue *)valueWithNullInContext:(JSContext *)context;
+ (JSValue *)valueWithUndefinedInContext:(JSContext *)context;


创建以后就可以通过JSContext来让JSValue可以在js中访问。

3.将JSValue转换成oc类型就是一些列to方法,例如toString。

4.调用JS中定义的方法

先通过JSContext获取到JS中定义的方法对象(保存在JSValue实例中),然后用JSValue实例调用下面的方法就可以执行这个JS方法了。

- (JSValue *)callWithArguments:(NSArray *)arguments;


5.访问JS中的对象

先通过JSContext获取到JS中定义的对象(保存在JSValue实例中),然后就可以访问这个对象的方法和属性。

- (JSValue *)constructWithArguments:(NSArray *)arguments;
- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;
- (void)setValue:(id)value atIndex:(NSUInteger)index;
- (JSValue *)valueAtIndex:(NSUInteger)index;
- (void)defineProperty:(NSString *)property descriptor:(id)descriptor;
- (void)setValue:(id)value forProperty:(NSString *)property;
- (BOOL)hasProperty:(NSString *)property;
- (JSValue *)valueForProperty:(NSString *)property;


JSExport协议让OC的类的方法和属性可以在js中访问

步骤:

先写一个协议,这个协议继承
<JSExport>


然后在这个协议中定义方法和属性。

最后在定义类的时候遵循这个属性。

那么当这个类的实例通过JSContext暴露到js中的时候,相关的协议方法和属性就可以被js访问到,那些不在协议中的属性和方法就不能被js访问。

Javascriptcore C语言接口总结

1.JSBase.h使用c语言语法给多个结构体指针命了别名以及三个针对js的方法:

结构体指针:

JSContextRef
表示上下文,持有当前上下文的一些全局对象以及运行状态

JSGlobalContextRef
表示全局上下文,其实和JSContextRef是同一类型的结构体

JSContextGroupRef
表示上下文组,同一个组中的上下文可互相访问彼此的持有的全局对象

JSStringRef
表示JS字符串,一个 UTF16 character buffer

JSClassRef
表示JS的类,还要看JSObjectRef

JSPropertyNameArrayRef
表示一个装有js属性名的数组

JSPropertyNameAccumulatorRef
表示一个装有js属性名的有序集合

JSValueRef
表示一个js中的值,具体来说,是某个js上下文中的某个变量

JSObjectRef
和JSValueRef是同一类型的结构体,但用这个来表示js中的对象

方法:

一个执行js语句的方法(哈哈看头文件去,我这个只是总结)

一个检查js语法的方法

一个回收js垃圾的方法,当整个上下文组被release掉的时候,在该上下文中的变量都会被回收。

2.

对应的以以上结构体指针的别名命名的.h文件,定义的都是针对该结构体指针的一些操作的方法,参数通常是一个
JSContextRef
,以及一个对应的结构体指针。如,JSValueRef.h定义了的方法参数很多都有一个
JSContextRef
和一个
JSValueRef
,比如这个。

bool JSValueIsArray(JSContextRef ctx, JSValueRef value)


这是JSValueRef.h里面定义的判断某一个JSValueRef所代表的JS值是不是一个数组的方法。

除此以外,还定义了一些方法,可以将一个c类型转换成一个JSValueRef结构体,还有

从JSValue中获取c基本类型值,还有一些可以将JSValueRef和其他的结构体指针类型互相转换的方法,比如转换成JSStringRef。

3.多个头文件都出现的这个东西:

#ifdef __cplusplus
extern "C" {
#endif


上面的意思是,如果该程序是c++程序,就定义
extern “C”{


__cplusplus
表示程序是c++程序。

extern “C”{
...
}


上面这样把一些代码括起来,是用在c和c++混用的文件里面,表示括起来的这段代码要用c语言的编译规则进行编译。c++和c语言编译规则不同,编译出来的函数名标识符不一样,c的函数编译过来还是原来的名字,c++就不一定,因为c++存在函数的重载,就是允许存在相同名称但参数不同的函数,对于这些相同名称的函数编译过后要区分开来就不能还是原来的名字,通常会和参数结合起来命名,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javaScript core framework oc c