繁体   English   中英

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

[英]Why can't I get the variable name as a string? I want to create my own 'console.log' function

我是一个初学者,我经常需要查看变量的值以确保我为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秒。

如果不对源代码进行额外处理,就不可能做到这一点。 在运行时,该函数将传递一个 ,它无法知道该值来自何处。

您可以改为使其接受一个对象,然后可以通过以下方式调用它:

mylog({phone_number, name, address});

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

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

(简写在旧版浏览器中不起作用)

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


我可以将此功能添加到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" ) ) ; 

原始答案

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

您还可以获取该函数的主体, 如此答案中所述

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

并通过单行代码在需要的地方添加mylog:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM