TL;DR
Best to leave the actual console alone, not least because interfering with it can prevent asking and answering questions related to the console (such as when and how data is expanded on V8's console, which is a non-trivial thing).
Snippets definitely need a built-in, simple means of generating output without promoting poor practices like
document.write
.Specific suggestion for what to provide below, including a version hosted on GitHub Pages for use until/unless Snippets have their own way.
I think the console should be left alone, not least because interfering with it can prevent asking and answering questions related to the console (such as when and how data is expanded on V8's console, which is a non-trivial thing).
But I'm very keen to see what I think is the main point of this request: A simple means of writing output to the output pane of the snippet.
Right now, people are doing four things:
Using
document.write
. This is awful, it promotes 1990s code in 2014+.Using some function for output, like my usual:
function display(msg) { document.body.insertAdjacentHTML( "beforeend", "<p>" + msg + "</p>" ); }
This is also not good, because it adds a lot of noise, esp. to short snippets.
Using
console.log
, which just makes the output pane of the snippet wasted space.Writing scripts they include in snippets (like mine below), which means the snippet relies on an off-site resource.
None of those is a good solution.
My suggestion is Keep It Simple and inject a snippet
object into snippets (without showing it in the snippet) with a log
(or whatever) method; perhaps both log
and logHTML
:
// MIT license, see: https://github.com/tjcrowder/simple-snippets-console/blob/master/LICENSE
var snippet = {
version: "1.1",
// Writes out the given text in a monospaced paragraph tag, escaping
// & and < so they aren't rendered as HTML.
log: function(msg, tag) {
var elm = document.createElement(tag || "p");
elm.style.fontFamily = "monospace";
elm.style.margin = "2px 0 2px 0";
if (Object.prototype.toString.call(msg) === "[object Array]") {
msg = msg.join();
} else if (typeof object === "object") {
msg = msg === null ? "null" : JSON.stringify(msg);
} else {
msg = String(msg);
}
elm.innerHTML = msg.replace(/&/g, '&').replace(/</g, '<');
document.body.appendChild(elm);
},
// Writes out the given HTML at the end of the body,
// exactly as-is
logHTML: function(html) {
document.body.insertAdjacentHTML("beforeend", html);
}
};
I've made a version available here on GitHub Pages for use until snippets have their own way of doing it. Feel free to insert that at the top of a snippet like this:
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
A simple snippet
object like that solves the issues with what people are doing now. Consider this example:
Question:
How do I create an array with just a subset of the contents of an existing array in JavaScript? For instance, only non-negative numbers?
Answer:
You can use ES5's Array#filter
for that. It calls a function you supply, passing in each entry in the array, and builds a new array from the entries you return a truthy value for:
var a = [10, 0, -5, 7, 12, -3, -1];
var filtered = a.filter(function(entry) {
return entry >= 0;
});
snippet.log("original: " + a.join(", ")); // "10, 0, -5, 7, 12, -3, -1"
snippet.log("filtered: " + filtered.join(", ")); // "10, 0, 7, 12"
(Obviously if you try to run that, you'll get an error, as snippet
isn't defined.)
Isn't that better than:
var a = [10, 0, -5, 7, 12, -3, -1];
var filtered = a.filter(function(entry) {
return entry >= 0;
});
display("original: " + a.join(", ")); // "10, 0, -5, 7, 12, -3, -1"
display("filtered: " + filtered.join(", ")); // "10, 0, 7, 12"
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" + msg + "</p>"
);
}