是否可以在JavaScript中创建一个提供持久本地范围的控制台?

时间:2015-08-08 22:22:52

标签: javascript browser

我想在一个具有持久范围的Web应用程序的JavaScript中创建一个控制台(想想chrome的开发控制台)。所以你可以说,设置一个变量,然后在控制台中访问该变量。有一种简单的方法可以在JavaScript中执行此操作吗?

示例会话:

{{1}}

4 个答案:

答案 0 :(得分:3)

您可以使用对eval的间接调用。

直接调用不会起作用,因为它们会使用调用执行上下文,这可能会在创建变量和尝试访问变量之间发生变化。

相反,对eval的间接调用将使用全局执行上下文,因此变量将保持不变。

var myEval = eval; myEval(...)进行间接调用的一些方法是使用window.eval(...)var input = document.getElementById('input'), data = document.getElementById('data'); document.getElementById('form').onsubmit = function() { var code = input.value, result = window.eval(code); data.appendChild(document.createElement('dt')).appendChild(document.createTextNode(code)); data.appendChild(document.createElement('dd')).appendChild(document.createTextNode(result)); return false; };



<form id="form">
  <dl id="data"></dl>
  <input id="input" />
  <input type="submit" />
</form>
&#13;
var x = 5
&#13;
&#13;
&#13;

例如,在上面的代码段中,输入x。然后输入5,您将收到appcfg.py --no_cookies --oauth2 --email=myemail --noauth_local_webserver update .

答案 1 :(得分:3)

假设您正在使用基于eval的实现,您可以创建一个iframe来创建单独的执行上下文。然后,您可以使用其全局eval函数来计算隔离执行上下文中的表达式。上下文将保持评估之间的状态。

var iframe = document.createElement('iframe');

// We have to attach the iframe to the document to get a new execution context.
document.body.appendChild(iframe);

// Now the console implementation is simply the context's eval function.
var myConsole = iframe.contentWindow.eval;

myConsole('function SomeCustomFunction() { return "the result"; }');
myConsole('var x = SomeCustomFunction()'); // "the result"
myConsole('x.slice(4)'); // "result"

答案 2 :(得分:1)

我知道这并不是你所要求的。

您可以使用devtools.inspectedWindow API https://developer.chrome.com/extensions/api_index#stable_apis开发Google Chrome扩展程序。

&#34;使用chrome.devtools.inspectedWindow API与检查的窗口进行交互:获取被检查页面的选项卡ID,在检查窗口的上下文中评估代码,重新加载页面或获取列表页面内的资源。&#34;

您的范围已绑定到该页面。

答案 3 :(得分:1)

// create object
var obj = {};
// define property `console`
obj.console = {};
// define `log` property of `obj.console`
obj.console.log = function(name, args) { 
  // if `obj.console.log` called without `args`
  // and `name` defined at `obj` , return `obj[name]`
  // else set `obj[name]`  , return  `obj[name]`
  if (name !== undefined && args === undefined && obj[name]) return obj[name]
  else obj.setProps(name, args); return obj[name]
};

obj.setProps = function setProps(name, args) {
  // if `name` is not reserved `"log"` , set `obj[name]` to `args`
  // persist `obj[name]` at local scope of `obj`
  if (!this[name] && name !== "log") this[name] = args;
}

function SomeCustomFunction() {
  return "the result"
}

var x = SomeCustomFunction();

// do stuff
obj.console.log("x", x);

console.log(obj.console.log("x"));

console.log(obj.console.log("x").slice(4));

// set `y` 
console.log(obj.console.log("y", Math.random() * 1000).toFixed(5));

console.log(obj.console.log("y"));

// set `obj` properties globally
// for (prop in obj) if (prop !== "log" && !window[prop]) window[prop] = obj[prop]