2015-08-08 15 views
6

Chciałbym utworzyć konsolę (uważam, że konsola programisty Chrome), w JavaScript dla aplikacji sieci Web, która ma stały zakres. Możesz więc powiedzieć, ustawić zmienną, a następnie uzyskać dostęp do tej zmiennej w dalszej części konsoli. Czy istnieje prosty sposób na to w JavaScript?Czy można utworzyć konsolę w JavaScript, która zapewnia stały zakres lokalny?

Przykładem sesja:

var x = SomeCustomFunction() 
>> "the result" 
x.slice(4) 
>> "result" 

Odpowiedz

3

Można używać połączeń pośrednich do numeru eval.

Bezpośrednie połączenia nie będą działać, ponieważ będą używać kontekstu wykonywania wywołania, który prawdopodobnie zmieni się między utworzeniem zmiennej i próbą uzyskania do niej dostępu.

Zamiast tego, połączenia pośrednie do eval będą używać globalnego kontekstu wykonania, a zatem zmienne będą się utrzymywać.

Niektóre sposoby nawiązywania połączeń pośrednich z eval używają var myEval = eval; myEval(...) lub 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>

Na przykład, w powyższym fragmencie wprowadzić var x = 5. Następnie wpisz x, a otrzymasz 5.

+1

Ten 'eval' nie jest izolowany od kodu aplikacji. W związku z tym użycie konsoli może spowodować jej uszkodzenie (zniszczyć stan aplikacji). –

+1

@RickHitchcock Ponieważ połączenia pośrednie do eval zachowują się inaczej niż połączenia bezpośrednie. Zobacz [§10.4.2] (http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2) – Oriol

+0

@NoahFreitas True. Chciałem tylko zapewnić proste podejście, ale można je poprawić, uruchamiając kod w innym oknie, a także dodając "try ... catch", aby wychwycić błędy, dodając ładny wyświetlacz obiektów, ... – Oriol

1

wiem, że to nie jest dokładnie to, o co prosiliście.

Możesz rozwinąć rozszerzenie Google Chrome przy użyciu interfejsu API devtools.inspectedWindow https://developer.chrome.com/extensions/api_index#stable_apis.

"Użyj interfejsu API chrome.devtools.inspectedWindow do interakcji z kontrolowanym oknem: uzyskaj identyfikator karty dla sprawdzanej strony, oceń kod w kontekście kontrolowanego okna, załaduj ponownie stronę lub uzyskaj listę zasobów na stronie. "

Twój zakres jest związany ze stroną.

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]

3

Zakładając, że używasz eval opartych realizacji, można utworzyć iframe, aby utworzyć oddzielny kontekst wykonania. Następnie można użyć jego globalnej funkcji eval do oceny wyrażeń w izolowanym kontekście wykonania. Kontekst zachowa stan między ocenami.

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" 
Powiązane problemy