Reputation: 592
Im a beginner and I often need to see a variable's value to make sure I am picking the right method / property /selector for jQuery or just to see what the value is or debugging in general. So what I usually do is
console.log("phone_number: " + phone_number);
I want to create my own 'console.log' function where I simply put the variable(or many variables) as parameters and neatly print out the results.
mylog(phone_number, name, address);
would output to console:
phone_number: 911
name: stanek
address: undefined
Its not a huge deal typing out the first way but I feel like there must be a better way of doing it... and I want to save time.
The answers to previous related questions usually involve remarks such as 'you already know the name' or 'what good reason do you have for this'. I feel this scenario shows a specific need for this request.
I have a feeling that this isn't built into Javascript or it would have been in an answer somewhere.
My curious question is: Why isn't this a feature of Javascript?
My determined question: Is it possible for me to add this feature to Javascript? I'm willing to spend countless hours to save 20 seconds.
Upvotes: 0
Views: 203
Reputation:
If you don't mind to pass strings instead of identifiers, you could use eval().
Update: I've renamed mylog to _ and now it returns an object, this way you can use console.log() directly. The original snippet is at the bottom.
var phone_number = 911 ;
var name = "stanek" ;
function _( ){
function myeval( arg ){
try{
return eval( arg ) ;
}
catch( e ){
if( e instanceof ReferenceError ) return undefined ;
else throw e ;
}
}
var obj = {} ;
for( var i = 0 ; i < arguments.length ; ++i ){
obj[arguments[i]] = myeval( arguments[i] ) ;
}
return obj ;
}
console.log( _( "name", "phone_number", "address" ) ) ;
original answer:
var phone_number = 911 ;
var thename = "stanek" ;
function mylog( ){
function myeval( arg ){
try{
return eval( arg ) ;
}
catch( e ){
if( e instanceof ReferenceError ) return undefined ;
else throw e ;
}
}
for( var i = 0 ; i < arguments.length ; ++i ){
console.log( arguments[i] + ": " + myeval( arguments[i] ) ) ;
}
}
mylog( "phone_number", "thename", "address" ) ;
You could also get the body of the function, as explained in this answer:
var mylogstr = mylog.toString( ) ;
var mylogbody = mylogstr.slice( mylogstr.indexOf("{") + 1, mylogstr.lastIndexOf("}")) ;
And add mylog wherever you need with a single line of code:
var mylog = function( ){ eval( mylogbody ) ; } ;
Upvotes: 1
Reputation: 8458
In javascript, scoped variables exist only in the runtime engine and don't expose their name for introspection. This is by opposition to, for example, object variables. Your request could be achieved by using an object instead of the scope to store your variables:
let _ = {
phone_number: 911,
name: stanek,
address: undefined,
}
let log = function() {
for (let name of arguments)
console.log(name, ":", scope[name]);
}
log("phone_number", "name", "address");
_.name = "New Name";
As you can see, this technique requires a bit of prefixing when addressing the variables, but it's not different from this.
; speaking of which the same technique could work with this.
as well. Let me see:
let log = function() {
for (let name of arguments)
console.log(name, ":", this.name);
}
_.log = log;
_.log("name");
this.log = log;
this.log("foo", "bar", "buz");
or
log.call(_, "name");
log.call(this, "foo", "bar", "buz");
Upvotes: 0
Reputation: 816472
It's not possible to do this without additional processing of the source code. At runtime, the function gets passed a value, it cannot know where the value came from.
You can make it accept an object instead and then it can be called with:
mylog({phone_number, name, address});
This uses short object notation introduced in ES2015 which is equivalent to
mylog({phone_number: phone_number, name: name, address: address});
(short notation won't work in older browsers)
This gives you access the value and the name of the variable (as object property).
Is it possible for me to add this feature to Javascript?
Unless you want to write your own JavaScript engine, no.
However you can use a source code transformer such as Babel to instrument your code before executing it. Here is an example of how such as Babel plugin could look like:
export default function ({types: t}) {
return {
visitor: {
CallExpression(path) {
if (path.node.callee.name !== 'mylog') {
return;
}
path.node.arguments = [
t.objectExpression(
path.node.arguments.map(arg => t.objectProperty(
t.StringLiteral(arg.name),
path.scope.hasReference(arg.name) ?
arg :
t.identifier('undefined')
))
),
];
}
}
};
}
This converts
var phone_number = 42;
var name = 'foo';
mylog(phone_number, name, address);
into
var phone_number = 42;
var name = 'foo';
mylog({
'phone_number': phone_number,
'name': name,
'address': undefined
});
Live demo: http://astexplorer.net/#/0Ph74qUjvL
Upvotes: 8