简体   繁体   English

在 JavaScript 中获取 object 变量名称

[英]Getting the object variable name in JavaScript

I am creating a JavaScript code and I had a situation where I want to read the object name (string) in the object method.我正在创建一个 JavaScript 代码,我有一种情况,我想在 object 方法中读取 object 名称(字符串)。 The sample code of what I am trying to achieve is shown below:我试图实现的示例代码如下所示:

// Define my object
var TestObject = function() {
    return {
        getObjectName: function() {
            console.log( /* Get the Object instance name */ );
        }
    };
}

// create instance
var a1 = TestObject();
var a2 = TestObject();

a1.getObjectName(); // Here I want to get the string name "a1";

a2.getObjectName(); // Here I want to get the string name "a2";

I am not sure if this is possible in JavaScript.我不确定这在 JavaScript 中是否可行。 But in case it is, I would love to hear from you guys how to achieve this.但如果是这样,我很想听听你们如何实现这一目标。

This is not possible in JavaScript.这在 JavaScript 中是不可能的。 A variable is just a reference to an object, and the same object can be referenced by multiple variables.一个变量只是对一个对象的引用,同一个对象可以被多个变量引用。 There is no way to tell which variable was used to gain access to your object.无法判断哪个变量用于访问您的对象。 However, if you pass a name to your constructor function you could return that instead:但是,如果您将name传递给构造函数,则可以返回该名称:

 // Define my object function TestObject (name) { return { getObjectName: function() { return name } }; } // create instance var a1 = TestObject('a1') var a2 = TestObject('a2') console.log(a1.getObjectName()) //=> 'a1' console.log(a2.getObjectName()) //=> 'a2'

This is definitely possible but is a bit ugly for obvious reasons.这绝对是可能的,但由于显而易见的原因有点难看。 I think this can have some application in debugging.我认为这在调试中可以有一些应用。 The solution makes use of the ability to get the line number for a code using Error object and then reading the source file to get the identifier.该解决方案利用了使用Error对象获取代码行号的能力,然后读取源文件以获取标识符。

let fs = require('fs');
class Foo {
    constructor(bar, lineAndFile) {
        this.bar = bar;
        this.lineAndFile = lineAndFile;
    }
    toString() {
        return `${this.bar} ${this.lineAndFile}`
    }
}
let foo = new Foo(5, getLineAndFile());

console.log(foo.toString()); // 5 /Users/XXX/XXX/temp.js:11:22
readIdentifierFromFile(foo.lineAndFile); // let foo

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

function getLineAndFile() {
    let err = getErrorObject();
    let callerLine = err.stack.split("\n")[4];
    let index = callerLine.indexOf("(");
    return callerLine.slice(index+1, callerLine.length-1);
}

function readIdentifierFromFile(lineAndFile) {
    let file = lineAndFile.split(':')[0];
    let line = lineAndFile.split(':')[1];
    fs.readFile(file, 'utf-8', (err, data) => { 
        if (err) throw err; 
        console.log(data.split('\n')[parseInt(line)-1].split('=')[0].trim());
    }) 
}

Depending on what your needs are, there are some creative solutions.根据您的需求,有一些创造性的解决方案。 The main place I want to know a variable name is when I'm debugging .我想知道变量名的主要地方是我在调试时

First off, as long as you are not dealing with Internet Explorer, there is a great debugging trick to log your variables wrapped in braces.首先,只要您不使用 Internet Explorer,就有一个很好的调试技巧来记录包含在大括号中的变量。 The console will show you the details of your "object"... which has only one key, the exact name of your variable!控制台将向您显示“对象”的详细信息……它只有一个键,即变量的确切名称!

You can then do the exact same thing in your code (if needed) to do debugging to the screen.然后,您可以在代码中执行完全相同的操作(如果需要)以对屏幕进行调试。

 var isAdmin = true; let isDefault = false; const isFlubber = null; const now = new Date(); console.log({isAdmin}); console.log({isDefault}); console.log({isFlubber}); console.log({now}); //You can also use console.dir() or console.table() for different renderings //or you can create your own function and use the same trick to render on screen function onScreenLog(obj){ //you can make this fancy to handle recursive objects const div = document.getElementById('onscreen-log'); for(const [key, value] of Object.entries(obj)){ div.innerHTML += key + ': <b>' + value + '</b><br/>'; } } onScreenLog({isAdmin}); onScreenLog({isDefault}); onScreenLog({isFlubber}); onScreenLog({now});
 <div id="onscreen-log" style="background=color:#fffedf;border:1px solid #ddd;font-family:sans-serif;height:75px;padding:2px;"></div>

Credit goes to this article 's author:归功于这篇文章的作者:


// Define my object
function TestObject (name) {
    return {
        getObjectName: function() {
            return name
        }
    };
}

// create instance
const a1 = TestObject('a1')
const a2 = TestObject('a2')

const [a1Name] = Object.keys({a1})
const [a2Name] = Object.keys({a2})

console.log(a1Name) //=> 'a1'

console.log(a2Name) //=> 'a2'

With objects that are serializable, in supports contexts like HTTPS,使用可序列化的对象,支持 HTTPS 等上下文,

 for (itr in window) {
   try {
      if (JSON.stringify(window[itr]) == JSON.stringify(this)) {
        console.info(itr) //return itr
    }
} catch (err) {}
};

It is possible if:如果出现以下情况可能的:

  1. Your variables are available in the global space您的变量在全局空间中可用
  2. and redefine TestObject so that it can be instantiated.并重新定义TestObject以便它可以被实例化。

 // Define my object function TestObject(){} TestObject.prototype.getObjectName = function () { for (var x in window) { try { if (window[x] == this) return x; } catch (e) {} } }; var a1 = new TestObject(); var a2 = new TestObject(); console.log(a1.getObjectName()); console.log(a2.getObjectName());

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

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