编程技术记录

世界你好!

JavaScript 原生中默认是没有 Console 对象,这是宿主对象提供的内置对象。
在webview中已经内置实现了,但是在JSCore这样的JS引擎中没有实现相关功能,因此为了前端同学调试方便和代码可移植性,有必要手动实现一个。
大体的实现思路如下:

注入全局的日志打印函数

我们可以注入一个全局的日志打印函数,假设名字叫做NativePrint,然后创建Console对象,将Console对象的日志输出全部转发到这个NativePrint上。

NativePrint接收两个参数,一个是日志类型,一个日志内容.

iOS JSContext示例

JSContext * context = [JSContext new];
context[@"NativePrint"] = ^(NSString *logType , id logContext) {
        //打印输出
}

Android V8示例

import com.eclipsesource.v8.V8;

JavaVoidCallback callback = new JavaVoidCallback() {
    @Override
    public void invoke(final V8Object receiver, final V8Array parameters) {
        //解析parameters ,打印输出
    }
}

V8 runtime = V8.createV8Runtime();
runtime.registerJavaMethod(callback, "NativePrint");

注入Console对象

可变参数

对于JavaScript的方法来说,都有一个arguments参数列表(列表名字就是arguments),所以我们可以定义可变参数函数

javascript代码

注入NativePrint方法后,我们再注入一个全局的Console对象,
例如

console = {

  default:this,

  __Stringformat : function (values) {

    function __toString(s)
    {
      if (s === null || s === undefined) {
          return "";
      }
      return s.toString();
    }

    if (values.length == 0) {
      return "";
    } else if (values.length == 1) {
      return __toString(values[0]);
    }

    index = 0;
    return values[0].replace(/%([a-zA-Z_])/g, function (match) {
      index = index +1;
      if (values.length > index) {
        return __toString(values[index]);
      } else {
        return "";
      }
    });
  }, 
  info : function () {
    ffpd_log("info",this.__Stringformat(arguments));
  },

  warn : function () {
    ffpd_log("warn",this.__Stringformat(arguments));
  },

  //其他Console方法
};

使用示例

console.info("%s %s %i","hello","world", 100);

发表回复

© Beli. All Rights Reserved.