重写console.log的一些理解

关于重写console.log的方式通常都是这样的:

  

console.log = (function(oriLogFunc){
      return function(str)
      {
          oriLogFunc.call(console,"hello:"+str);
      }
    })(console.log);
    console.log("dami");

 在这里,通过立即执行函数传入console.log参数,然后返回一个方法,而在返回的方法里面保持了对console.log的引用,这其实是一个闭包,所以我们重写了console.log却仍然可以使用console.log方法的原因:console.log指向一个方法,这个方法实现了输出功能,console.log只是指向那里,然后当作参数传入立即执行函数后,在立即执行函数里面我们实际上拿到的也是这个指向输出方法的地址,而console.log不过是个表皮,所以最重要的是拿到对输出方法的引用,并并保持这个引用,所以如果是这样,不使用闭包也是可以的

var log = console.log;
    console.log = function(text){
      log("info"+text);
      //log.call(console,"info"+text);//使用call让log里面的this指向console,而不是window
    }
    console.log("dami")

在这里我们把console.log赋值给log 这样log就拿到了对输出方法的引用,所以下面重写console.log的时候我们可以使用log来输出,这里有个注意点,在注释部分,我们应该使用log.call(console,"")而不是直接使用log来输出,这牵涉到log方法里this指向的问题,如果直接使用log()那this指向window,这显然不是我们希望的,我们希望他向console.log方法一样指向console,所以这里要使用log.call(console,"")

转载于:https://www.cnblogs.com/mrzhu/p/8440428.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要获取 CEF 中的 `console.log` 内容,可以使用 `CefMessageRouterBrowserSide` 类来实现。 以下是一个简单的例子,展示如何使用 `CefMessageRouterBrowserSide` 来获取 `console.log` 内容: ```cpp // 创建一个实现了 CefMessageRouterBrowserSide::Handler 接口的对象 class ConsoleMessageHandler : public CefMessageRouterBrowserSide::Handler { public: // 处理 JavaScript 发送过来的消息 virtual bool OnQuery(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int64 query_id, const CefString& request, bool persistent, CefRefPtr<Callback> callback) OVERRIDE { if (request == "get-console-log") { // 获取 console.log 内容并发送回去 CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("console-log"); message->GetArgumentList()->SetString(0, GetConsoleLog()); browser->SendProcessMessage(PID_BROWSER, message); return true; } return false; } // 获取 console.log 内容 CefString GetConsoleLog() { CefRefPtr<CefFrame> frame = browser_->GetMainFrame(); CefRefPtr<CefV8Context> context = frame->GetV8Context(); CefRefPtr<CefV8Value> window = context->GetGlobal(); CefRefPtr<CefV8Value> console = window->GetValue("console"); CefRefPtr<CefV8Value> logFn = console->GetValue("log"); CefRefPtr<CefV8Value> logArray = CefV8Value::CreateArray(0); CefRefPtr<CefV8Exception> exception; CefRefPtr<CefV8Value> result = logFn->ExecuteFunctionWithContext(context, window, logArray); CefString consoleLog; if (result->IsArray()) { CefRefPtr<CefV8Value> arr = result; int len = arr->GetArrayLength(); for (int i = 0; i < len; i++) { CefRefPtr<CefV8Value> val = arr->GetValue(i); consoleLog += val->GetStringValue() + "\n"; } } return consoleLog; } IMPLEMENT_REFCOUNTING(ConsoleMessageHandler); }; // 创建一个实现了 CefRenderProcessHandler 接口的对象 class RenderProcessHandler : public CefRenderProcessHandler { public: // 创建一个 CefMessageRouterBrowserSide 对象 virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE { CefRefPtr<CefMessageRouterBrowserSide> messageRouter = CefMessageRouterBrowserSide::Create( CefMessageRouterBrowserSide::Config(), new ConsoleMessageHandler()); messageRouter->AddHandler(new ConsoleMessageHandler(), false); messageRouter->OnContextCreated(browser, frame, context); } // 注册一个 JavaScript 扩展 virtual void OnWebKitInitialized() OVERRIDE { CefRegisterExtension("console", "var console = {log: function() {native function consoleLog(); consoleLog(Array.prototype.slice.call(arguments));}};", new ConsoleMessageHandler()); } IMPLEMENT_REFCOUNTING(RenderProcessHandler); }; ``` 在上面的代码中,我们首先创建了一个实现了 `CefMessageRouterBrowserSide::Handler` 接口的对象 `ConsoleMessageHandler`。该对象实现了 `OnQuery` 方法,用于处理 JavaScript 发送过来的消息。当接收到 `get-console-log` 消息时,我们调用 `GetConsoleLog` 方法获取 `console.log` 内容,并将其发送回 JavaScript 端。 `GetConsoleLog` 方法首先获取当前浏览器上下文和主框架,然后使用 `CefV8Context::GetGlobal` 方法获取全局对象。接着,我们使用 `CefV8Value::GetValue` 方法获取 `console` 对象和 `log` 函数,并将其保存在 `logFn` 变量中。我们使用 `CefV8Value::CreateArray` 方法创建一个空的数组 `logArray`,并调用 `logFn->ExecuteFunctionWithContext` 方法执行 `console.log` 函数。最后,我们遍历返回的数组 `result`,获取每条 `console.log` 的内容,并将其保存在 `consoleLog` 变量中。 为了使 CEF 能够调用 `console.log` 函数,我们还需要在 `OnWebKitInitialized` 方法中注册一个 JavaScript 扩展。在这个扩展中,我们将 `console.log` 函数重写为一个 JavaScript 函数,该函数会调用 C++ 中的原生函数 `consoleLog`,并将 `console.log` 的参数传递给该函数。在 `consoleLog` 函数中,我们可以将 `console.log` 的参数保存起来,以便在需要时返回给 JavaScript 端。 最后,我们还需要在渲染进程中创建一个实现了 `CefRenderProcessHandler` 接口的对象 `RenderProcessHandler`,并在其中通过 `OnContextCreated` 方法创建一个 `CefMessageRouterBrowserSide` 对象,并将其注册到当前上下文中。通过这样的方式,我们就可以在 CEF 中获取 `console.log` 内容了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值