zoukankan      html  css  js  c++  java
  • JavaScriptCore

      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];
    View Code

      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}"];
    View Code

    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]);
    View Code

    4、JSContext和JSValue实例使用下标的方法,我们可以很容易的访问到我们之前创建的context的任何值。JSContext需要一个字符串下标,而JSValue允许字符串或整数下标来得到里面的对象和数组

     JSValue *names=context[@"names"];
        JSValue *initialName=names[0];
        NSLog(@"The first name :%@",[initialName toString]);
    View Code

    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]);
    View Code

    输出内容:

    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('안녕하새요!')"]);
    View Code

    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]);
    View Code

    这段跟第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

    大致就介绍这么多,希望对看到的朋友有点用……

  • 相关阅读:
    不应滥用named let
    PAT甲级——A1106 Lowest Price in Supply Chain
    PAT甲级——A1105 Spiral Matrix【25】
    PAT甲级——A1104 Sum of Number Segments
    PAT甲级——A1103 Integer Factorization
    PAT甲级——A1102 Invert a Binary Tree
    PAT甲级——A1101 Quick Sort
    PAT甲级——A1100 Mars Numbers
    PAT甲级——A1099 Build A Binary Search Tree
    PAT甲级——A1098 Insertion or Heap Sort
  • 原文地址:https://www.cnblogs.com/luseike/p/4331967.html
Copyright © 2011-2022 走看看