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

时间:2016-08-31 23:16:44

标签: javascript jquery

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

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

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

mylog(phone_number, name, address);

将输出到控制台:

phone_number: 911
name: stanek
address: undefined

第一种方式输入并不是一件大事,但我觉得必须有一种更好的方法......我希望节省时间。

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

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

我好奇的问题是:为什么这不是Javascript的一个功能?

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

3 个答案:

答案 0 :(得分:8)

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

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

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

这使用ES2015中引入的a fine point,相当于

var phone_number = 42;
var name = 'foo';

mylog(phone_number, name, address);

(简短表示法在旧版浏览器中无效)

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

  

我可以将此功能添加到Javascript吗?

除非您想编写自己的JavaScript引擎,否则编号

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

var phone_number = 42;
var name = 'foo';

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

这会转换

^2.4.2

node_modules

现场演示:Babel

答案 1 :(得分:1)

如果您不介意传递字符串而不是标识符,则可以使用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" ) ) ;

原始回答

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

您也可以获取该函数的主体,如this answer

中所述
var mylogstr = mylog.toString( ) ; 
var mylogbody = mylogstr.slice( mylogstr.indexOf("{") + 1, mylogstr.lastIndexOf("}")) ;

使用一行代码在任何地方添加mylog:

var mylog = function( ){ eval( mylogbody ) ; } ;

答案 2 :(得分:0)

在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.。让我看看:

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