标签:
JavaScript这门所谓的脚本的语言,在两年前我从事Web开发的时候,还只是把它当做HTML中操作DOM元素来改变一些常见属性的工具。那时我对JavaScript的认识还很局限,如今随着HTML5的火爆,JavaScript被我重新认知,它作为动态语言的强大,V8引擎的优化以及配合CSS3构建移动端网站的优势让我欣喜。今天介绍下苹果的JavaScriptCore,以后有时间会专门写一个JavaScript的专题,包括JavaScript基础、动画等内容……
没认识JavaScriptCore之前,如果想在Object-c中使用JavaScript代码,一般都是在webview这个uikit中(webview内置webkit引擎,解析JavaScript代码),如下这段代码主要调用webview的stringByEvaluatingJavaScriptFromString:方法,将HTML中所有li标签里的href属性进行修改。
NSMutableString *mutableStr=[NSMutableString string]; [mutableStr appendString:@"var lis=document.getElementsByTagName(‘li‘);"]; [mutableStr appendString:@"for(var i=0;i<lis.length;i++){"]; [mutableStr appendString:@"var aHref=lis[i].children[0].href;"]; [mutableStr appendString:@"var startIndex=aHref.indexOf(‘(‘);"]; [mutableStr appendString:@"var endIndex=aHref.indexOf(‘)‘);"]; [mutableStr appendString:@"var newStr=aHref.substr(startIndex+2,endIndex-startIndex-3);"]; [mutableStr appendString:@"lis[i].children[0].href=‘objc-‘+newStr;"]; [mutableStr appendString:@"}"]; [webView stringByEvaluatingJavaScriptFromString:mutableStr];
JavaScriptCore是什么呢?它其实是苹果封装的一个JavaScrip代码的运行环境(可见苹果对JavaScript也从小三扶上位了),可以很容易的创建代码来创建JavaScript的变量、进行各种计算甚至是定义function
使用前需导入#import <JavaScriptCore/JavaScriptCore.h>
使用方法:
1、创建环境
JSContext *context=[[JSContext alloc] init];
2、调用evaluateScript创建JavaScript代码
[context evaluateScript:@"var num=5+5"]; [context evaluateScript:@"var names=[‘Lusieke‘,‘Lemon‘,‘Honey‘]"]; [context evaluateScript:@"var triple=function(value){return value * 3}"]; [context evaluateScript:@"var sum=function(num1,num2){return num1+num2}"];
3、任何出自JSContext的值都被包裹在一个JSValue对象中。像JavaScript这样的动态语言需要一个动态类型(var),所以JSValue包装了每一个可能的JavaScript值:字符、数字、数组、对象和方法。JSValue包括一系列方法用于访问其可能的值以保证有正确的Foundation类型
JSValue *tripNum=[context evaluateScript:@"num"]; //输出10,即定义的JavaScript脚本中var num=5+5的值 NSLog(@"triple :%d",[tripNum toInt32]); JSValue *names=[context evaluateScript:@"names"]; //输出names数组的值 NSLog(@"names :%@",[names toArray]);
4、JSContext和JSValue实例使用下标的方法,我们可以很容易的访问到我们之前创建的context的任何值。JSContext需要一个字符串下标,而JSValue允许字符串或整数下标来得到里面的对象和数组
JSValue *names=context[@"names"]; JSValue *initialName=names[0]; NSLog(@"The first name :%@",[initialName toString]);
5、如何调用定义的JavaScript函数?JSValue包装了一个JavaScript函数,我们可以在Object-c代码中使用Foundation类型作为参数来直接调用该函数
JSContext *context=[[JSContext alloc] init]; [context evaluateScript:@"var sum = function sum(num1,num2){return num1+num2;}"]; JSValue *sumFunc=[context[@"sum"] callWithArguments:@[@2,@3]]; NSLog(@"2+3的和=%d",[sumFunc toInt32]);
输出内容:
2015-03-12 11:23:32.787 javaScriptCore[742:140647] 2+3的和=5
程序中JSValue类型的变量context[@"sum"]通过callWithArguments:传递Foundation类型的变量@2,@3来调用JavaScript函数sum,并输出计算后的值
6、对照第5点,JavaScript如何调用定义在Object-c中的方法呢?比较常用的方法是使用Block(大块头有大能力)
context[@"simplifyString"]=^(NSString *input){ NSMutableString *mutableString=[input mutableCopy]; CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, kCFStringTransformToLatin, NO); CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, kCFStringTransformStripCombiningMarks, NO); return mutableString; }; NSLog(@"%@",[context evaluateScript:@"simplifyString(‘?????!‘)"]);
OC定义的方法保存在Block类型的变量并直接塞到context环境中(这样才会被JavaScript调用)成为JavaScript的方法,之后用同样的evaluateScript:传参调用,这就又回到第5点的内容了,应该很好理解了吧……
7、JavaScript的调试一直是很多新手头疼的问题,JavaScriptCore既然风转了JavaScript的运行环境,自然有自己调试JS的招数
context.exceptionHandler=^(JSContext *context, JSValue *exception){ NSLog(@"JS Error :%@",exception); };
JSContext通过设置上下文的exceptionHandler属性,可以捕获JS的运行时错误,
exceptionHandler是一个接收一个JSContext引用和异常本身的回调处理
JSContext *context=[[JSContext alloc] init]; [context evaluateScript:@"var summ = function sum(num1,num2){return num1+num2;}"]; context.exceptionHandler=^(JSContext *context, JSValue *exception){ NSLog(@"JS Error :%@",exception); }; JSValue *sumFunc=[context[@"sum"] callWithArguments:@[@2,@3]]; NSLog(@"2+3的和=%d",[sumFunc toInt32]);
这段跟第5点相同的代码中,故意将方法名sum写成summ,有了exceptionHandler后的生活编译器会妥妥的给你报个error
2015-03-12 11:39:51.060 javaScriptCore[1088:180110] JS Error :TypeError: undefined is not an object
一个经典的JS错误undefined
大致就介绍这么多,希望对看到的朋友有点用……
标签:
原文地址:http://www.cnblogs.com/luseike/p/4331967.html