In interview, I was asked that any string for e.g. "Hello" should be consoled when below line of code is executed.
console.log(new X())
This should be achieved without any additional console.log statements.
I tried something like:
function X() { return "Hello"; }
But it is not returning a string. It is returning the newly created instance of X.
Was this a trick question?
tl; dr;
function X() {
return document.createTextNode("Hello");
}
console.log(new X()); //"Hello"
Explanation:
An immediate thought is to somehow use toString
, but it doesn't work. Logging a plain object or class that implements toString
will still output the object structure when you log it, so that won't work.
2 parts of the spec are key to solve this:
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new)
When a function is called with the new keyword, the function will be used as a constructor. new will do the following things:
...
- If the constructor function returns a non-primitive, this return value becomes the result of the whole new expression. Otherwise, if the constructor function doesn't return anything or returns a primitive,
newInstance
is returned instead.
You have little control of how a user defined class will be logged. But maybe there is a built in object that will log text, so we need to figure out what that might be, and then return it in the constructor. What built in objects log text?
(https://console.spec.whatwg.org/)
§ 1.1.6. log(...data)
Perform Logger("log", data).
§ 2.1. Logger(logLevel, args)
The logger operation accepts a log level and a list of other arguments. Its main output is the implementation-defined side effect of printing the result to the console.
§ 2.3. Printer(logLevel, args[, options])
The printer operation is implementation-defined. It accepts a log level indicating severity, a List of arguments to print...Elements appearing in args will be one of the following:
- JavaScript objects of any type.
- Implementation-specific representations of printable things such as a stack trace or group.
- Objects with either generic JavaScript object formatting or optimally useful formatting applied.
§ 2.3.3. Common object formats
Typically objects will be printed in a format that is suitable for their context.... An object with generic JavaScript object formatting is a potentially expandable representation of a generic JavaScript object. An object with optimally useful formatting is an implementation-specific, potentially-interactive representation of an object judged to be maximally useful and informative.
^^ Paydirt. We need to find an object that has an "optimally useful formatting" which is not the object tree. I couldn't find an exhaustive list, but lets think about it. I know offhand that logging a dom node logs the html tree instead of the object tree:
So I took a leap and guessed that logging a text node might just log the text, and it worked:
and there it is
function X() {
return document.createTextNode("Hello");
}
console.log(new X()); //"Hello"
class X {
constructor() {
return document.createTextNode("Hello");
}
}
console.log(new X()); // "Hello"
see also: