浅谈 JavaScriptCore

462 查看

本文由我们团队的王瑞华童鞋撰写。


OS X Mavericks 和 iOS 7 引入了 JavaScriptCore 库,它把 WebKit 的 JavaScript 引擎用 Objective-C 封装,提供了简单,快速以及安全的方式接入世界上最流行的语言。在项目的实际开发中,由于需要与 H5 端有交互,所以采用了JavaScriptCore的交互方式,借此参与该项目的机会,对JavaScriptCore也有了一些简单的了解。

JSContext/JSValue

JSContext 是 JavaScript 的执行环境。所有 JavaScript 执行发生的背景,以及所有 JavaScript 值被绑在这一个上下文中。JSContext 类似于 UIWindow 的概念,所有的执行都在改环境中发生:

代码最后一行,每个 JSValue 起源于 JSContext 和 持有它的强引用。当一个 JSValue 实例方法创造一个新的 JSValue时,该新 JSValue 起源于同一个 JSContext。 JSValue 包装了每一个可能的 JavaScript 值:字符串和数字;数组、对象和方法;甚至错误和特殊的 JavaScript 值诸如 null 和 undefined。

OBJECTIVE-C TYPE JAVASCRIPT TYPE
nil undefined
NSNull null
NSString string
NSNumber number, boolean
NSDictionary Object object
NSArray Array object
NSDate Date object
NSBlock (1) Function object (1)
id (2) Wrapper object (2)
Class (3) Constructor object (3)

下标支持

作为下标传递的对象键将被转换为一个 JavaScript 值, 然后值转换为一个用作获取属性名称的字符串。

该简易方法对应于以下两个方法:

调用方法

JSValue 包装了一个 JavaScript 函数,我们可以从 Objective-C 代码中使用 Foundation 类型作为参数来直接调用该函数。

JavaScript 调用

上面说明的 OC 调用 JavaScript 的方法。那么接下来,说明 JavaScript 访问 OC 定义的对象和方法。我粗浅的认为就是在遵守该协议后,JavaScript 就可以调用 OC 实现的方法和属性等。

让 JSContext 访问我们的本地客户端代码的方式主要有两种:JSExport 协议和block。

JSExport 协议

JSExport 提供一个将 OC 中的类、实例方法和属性等导出为 JavaScript 函数的方法。

该协议只包含了一个方法:

即当导出到 JavaScript 时,重命名一个 selector。

这就需要熟悉它的做法,当带有一个或多个参数的 seletor 转变为 JavaScript 的属性名字时,在默认情况下一个属性名字将采用以下方式生成:

  • 所有的冒号将从 Selector 当中移除掉
  • 任何一个后边跟着冒号的小写字母开头的单词将被改换为大写。

在这种默认的转换方式下,一个 selector 如 doFoo:withBar: 将被导为doFooWithBar 。这种默认的改变有可能被 JSExportAs 宏 所改写,例如将 doFoo:withBar: 导出为 doFoo 。实际写法如下:

请注意 JSExport 宏只可能适用于带有一个或更多的参数的selector。

Blocks

当一个 Objective-C block 被赋给 JSContext 里的一个标识符,JavaScriptCore 会自动的把 block 封装在 JavaScript 函数里。如下: