JavaScriptCore全面解析 (3)

一个JSContext对象对应了一个全局对象(global object)。例如web浏览器中中的JSContext,其全局对象就是window对象。在其他环境中,全局对象也承担了类似的角色,用来区分不同的JavaScript context的作用域。全局变量是全局对象的属性,可以通过JSValue对象或者context下标的方式来访问。

一言不合上代码:

JSValue *value = [context evaluateScript:@"var a = 1+2*3;"]; NSLog(@"a = %@", [context objectForKeyedSubscript:@"a"]); NSLog(@"a = %@", [context.globalObject objectForKeyedSubscript:@"a"]); NSLog(@"a = %@", context[@"a"]); / Output: a = 7 a = 7 a = 7

这里列出了三种访问JavaScript对象的方法

通过context的实例方法objectForKeyedSubscript

通过context.globalObject的objectForKeyedSubscript实例方法

通过下标方式

设置属性也是对应的。

API Reference

/* 为JSContext提供下标访问元素的方式 */ @interface JSContext (SubscriptSupport) /* 首先将key转为JSValue对象,然后使用这个值在JavaScript context的全局对象中查找这个名字的属性并返回 */ (JSValue *)objectForKeyedSubscript:(id)key; /* 首先将key转为JSValue对象,然后用这个值在JavaScript context的全局对象中设置这个属性。 可使用这个方法将native中的对象或者方法桥接给JavaScript调用 */ (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying>*)key; @end /* 例如:以下代码在JavaScript中创建了一个实现是Objective-C block的function */ context[@"makeNSColor"] = ^(NSDictionary *rgb){ float r = [rgb[@"red"] floatValue]; float g = [rgb[@"green"] floatValue]; float b = [rgb[@"blue"] floatValue]; return [NSColor colorWithRed:(r / 255.f) green:(g / 255.f) blue:(b / 255.f) alpha:1.0]; }; JSValue *value = [context evaluateScript:@"makeNSColor({red:12, green:23, blue:67})"]; 五、 JSValue

一个JSValue实例就是一个JavaScript值的引用。使用JSValue类在JavaScript和native代码之间转换一些基本类型的数据(比如数值和字符串)。你也可以使用这个类去创建包装了自定义类的native对象的JavaScript对象,或者创建由native方法或者block实现的JavaScript函数。

每个JSValue实例都来源于一个代表JavaScript执行环境的JSContext对象,这个执行环境就包含了这个JSValue对应的值。每个JSValue对象都持有其JSContext对象的强引用,只要有任何一个与特定JSContext关联的JSValue被持有(retain),这个JSContext就会一直存活。通过调用JSValue的实例方法返回的其他的JSValue对象都属于与最始的JSValue相同的JSContext。

img

每个JSValue都通过其JSContext间接关联了一个特定的代表执行资源基础的JSVirtualMachine对象。你只能将一个JSValue对象传给由相同虚拟机管理(host)的JSValue或者JSContext的实例方法。如果尝试把一个虚拟机的JSValue传给另一个虚拟机,将会触发一个Objective-C异常。

img

1. JSValue类型转换

JSValue提供了一系列的方法将native与JavaScript的数据类型进行相互转换:

img

2. NSDictionary与JS对象

NSDictionary对象以及其包含的keys与JavaScript中的对应名称的属性相互转换。key所对应的值也会递归地进行拷贝和转换。

[context evaluateScript:@"var color = {red:230, green:90, blue:100}"]; //js->native 给你看我的颜色 JSValue *colorValue = context[@"color"]; NSLog(@"r=%@, g=%@, b=%@", colorValue[@"red"], colorValue[@"green"], colorValue[@"blue"]); NSDictionary *colorDic = [colorValue toDictionary]; NSLog(@"r=%@, g=%@, b=%@", colorDic[@"red"], colorDic[@"green"], colorDic[@"blue"]); //native->js 给你点颜色看看 context[@"color"] = @{@"red":@(0), @"green":@(0), @"blue":@(0)}; [context evaluateScript:@"log('r:'+color.red+'g:'+color.green+' b:'+color.blue)"]; Output: r=230, g=90, b=100 r=230, g=90, b=100 r:0 g:0 b:0

可见,JS中的对象可以直接转换成Objective-C中的NSDictionary,NSDictionary传入JavaScript也可以直接当作对象被使用。

3. NSArray与JS数组

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxyzf.html