为什么我不能将变量名称作为字符串? 我想创建自己的’console.log’函数

我是一个初学者,我经常需要看到一个变量的值,以确保我为jQuery选择正确的方法/属性/选择器,或者只是为了查看值是什么或一般调试。 所以我通常做的是

console.log("phone_number: " + phone_number); 

我想创建自己的’console.log’函数,我只需将变量(或许多变量)作为参数,并巧妙地打印出结果。

 mylog(phone_number, name, address); 

将输出到控制台:

 phone_number: 911 name: stanek address: undefined 

在第一种方式打字并不是一件大事,但我觉得必须有一个更好的方法来做到这一点……我想节省时间。

以前相关问题的答案通常包括诸如“你已经知道名字”或“你有什么好理由”这样的评论。 我觉得这个场景显示了对此请求的特定需求。

我有一种感觉,这不是内置于Javascript中,或者它本来就是在某个地方。

我好奇的问题是:为什么这不是Javascript的function?

我确定的问题:我可以将此function添加到Javascript中吗? 我愿意花费无数个小时来节省20秒。

如果不对源代码进行额外处理,则无法执行此操作。 在运行时,函数传递一个 ,它无法知道值的来源。

您可以让它接受一个对象,然后可以调用它:

 mylog({phone_number, name, address}); 

这使用ES2015中引入的短对象表示法 ,相当于

 mylog({phone_number: phone_number, name: name, address: address}); 

(简短表示法在旧版浏览器中不起作用)

这使您可以访问变量的值和名称(作为对象属性)。


我可以将此function添加到Javascript中吗?

除非你想编写自己的JavaScript引擎,否则没有。

但是,在执行代码之前,您可以使用Babel等源代码转换器来检测代码。 以下是Babel插件的外观示例:

 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') )) ), ]; } } }; } 

这转换

 var phone_number = 42; var name = 'foo'; mylog(phone_number, name, address); 

 var phone_number = 42; var name = 'foo'; mylog({ 'phone_number': phone_number, 'name': name, 'address': undefined }); 

现场演示: http : //astexplorer.net/#/0Ph74qUjvL

如果您不介意传递字符串而不是标识符,则可以使用eval()。
更新 :我已将mylog重命名为_,现在它返回一个对象,这样就可以直接使用console.log()了。 原始片段位于底部。

 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" ) ) ; 

在javascript中,范围变量仅存在于运行时引擎中,并且不公开其内部名称以进行内省。 这与例如对象变量相反。 您的请求可以通过使用对象而不是范围来存储变量来实现:

 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"; 

正如您所看到的,这种技术在处理变量时需要一些前缀,但它与this.没有区别this. ; 说到同样的技术可以用于this. 同样。 让我看看:

 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");