获取对象属性名称作为字符串

CLi*_*FoS 47 javascript string properties object

是否可以将对象属性名称作为字符串

person = {};
person.first_name = 'Jack';
person.last_name = 'Trades';
person.address = {};
person.address.street = 'Factory 1';
person.address.country = 'USA';
Run Code Online (Sandbox Code Playgroud)

我想像这样使用它:

var pn = propName( person.address.country ); // should return 'country' or 'person.address.country'
var pn = propName( person.first_name );      // should return 'first_name' or 'person.first_name'
Run Code Online (Sandbox Code Playgroud)

先谢谢你

注意:此代码正是我正在寻找的.我明白这听起来很愚蠢,但事实并非如此.

这就是我想用它做的事情.

HTML

person = {};
person.id_first_name = 'Jack';
person.id_last_name = 'Trades';
person.address = {};
person.address.id_address = 'Factory 1';
person.address.id_country = 'USA';


extPort.postMessage
(
  {
    message : MSG_ACTION,
    propName( person.first_name ): person.first_name
  }
};
Run Code Online (Sandbox Code Playgroud)

---------------------- ANSWER -----------------------

得到它归功于ibu.他用正确的方式指出,我使用了一个递归函数

var res = '';

function propName(prop, value) {
    for (var i in prop) {
        if (typeof prop[i] == 'object') {
            if (propName(prop[i], value)) {
                return res;
            }
        } else {
            if (prop[i] == value) {
                res = i;
                return res;
            }
        }
    }
    return undefined;
}

var pn = propName(person, person.first_name); // returns 'first_name'
var pn = propName(person, person.address.country); // returns 'country'
Run Code Online (Sandbox Code Playgroud)

演示:http://jsbin.com/iyabal/1/edit

小智 23

我知道使用Object.keys(your_object)的最佳实践.它将为您解析数组属性名称.例:

var person = { firstName: 'John', lastName: 'Cena', age: '30' };
var listPropertyNames = Object.keys(person); //["firstName", "lastName", "age"]
Run Code Online (Sandbox Code Playgroud)

我希望这个例子对你有用.

  • 这并不能回答问题,因为它将返回一个键数组。答案应该返回一个字符串值 (11认同)

小智 9

我在 TypeScript 中使用以下内容。这种方式保留类型信息并不允许选择不存在的属性键。

export function getPropertyName<T extends object>(obj: T, selector: (x: Record<keyof T, keyof T>) => keyof T): keyof T {
  const keyRecord = Object.keys(obj).reduce((res, key) => {
    const typedKey = key as keyof T
    res[typedKey] = typedKey
    return res
  }, {} as Record<keyof T, keyof T>)
  return selector(keyRecord)
}

const obj = {
  name: 'test',
  address: {
    street: 'test',
  }
}

console.log(getPropertyName(obj, (x) => x.name)) // name
console.log(getPropertyName(obj.address, (x) => x.street)) // street
Run Code Online (Sandbox Code Playgroud)


Dav*_*ret 8

您可以将属性包装在函数中,然后将函数转换为字符串并从中获取属性.

例如:

function getPropertyName(propertyFunction) {
    return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1];
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

var myObj = {
    myProperty: "testing"
};

getPropertyName(function() { myObj.myProperty; }); // myProperty
Run Code Online (Sandbox Code Playgroud)

请注意,缩小器可以打破这个.

编辑:我创建了一个与babel和typescript编译器一起使用的编译器转换(参见ts-nameof).这比在运行时执行某些操作更可靠.


Bl1*_*zak 7

您可以通过将所有对象属性转换为将返回其自身名称的函数来完成此操作

var person = {};
person.firstname = 'Jack';
person.address = "123 Street";

function getPropertyName(obj, expression) {
    var res = {};
    Object.keys(obj).map(k => { res[k] = () => k; });
    return expression(res)();
}

let result = getPropertyName(person, o => o.address);
console.log(result); // Output: 'address'
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的解决方案! (6认同)
  • 仅供参考,如果有人需要的话,我在下面添加了一个 TypeScript 版本。 (3认同)

Isk*_*k1n 7

使用代理:

var propName = ( obj ) => new Proxy(obj, {
    get(_, key) {
        return key;
    } 
});


var person = {};
person.first_name = 'Jack';
person.last_name = 'Trades';
person.address = {};
person.address.street = 'Factory 1';
person.address.country = 'USA';

console.log(propName(person).first_name);
console.log(propName(person.address).country);
Run Code Online (Sandbox Code Playgroud)


Nim*_*rod 7

我喜欢一个衬垫,这是一个通用的解决方案:

const propName = (obj,type) => Object.keys(obj).find(key => obj[key] === type)

propName(person, person.age)
Run Code Online (Sandbox Code Playgroud)

  • 如果两个键的值相同,这将给出错误的结果。例如:`人= {旧:25,姓名:'约翰',年龄:25};propName(人, 人.年龄); // 返回“旧”` (2认同)

Ibu*_*Ibu 6

是的,您可以做一些改动。

function propName(prop, value){
   for(var i in prop) {
       if (prop[i] == value){
            return i;
       }
   }
   return false;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以像这样获得值:

 var pn = propName(person,person.first_name);
 // pn = "first_name";
Run Code Online (Sandbox Code Playgroud)

注意我不确定它可以用于什么。

其他注释不适用于嵌套对象。但是再说一次,请参阅第一个注释。

  • 假设对象中没有两个属性具有相同的值。 (20认同)

Mad*_*unk 5

如果有人正在寻找 MarsRobot 答案的 TypeScript 版本,请尝试以下操作:

function nameof<T>(obj: T, expression: (x: { [Property in keyof T]: () => string }) => () => string): string
{
    const res: { [Property in keyof T]: () => string } = {} as { [Property in keyof T]: () => string };

    Object.keys(obj).map(k => res[k] = () => k);

    return expression(res)();
}
Run Code Online (Sandbox Code Playgroud)

用法:

const obj = { 
    property1: 'Jim',
    property2: 'Bloggs',
    property3: 'Bloggs',
    method: () => 'a string',
    child: { property4: 'child1' }
};

const test1 = nameof(obj, x => x.property1);
const test2 = nameof(obj, x => x.property2);
const test3 = nameof(obj, x => x.method);
const test4 = nameof(obj.child, x => x.property4);

console.log(test1);    // -> 'property1'
console.log(test2);    // -> 'property2'
console.log(test3);    // -> 'method'
console.log(test4);    // -> 'property4'
Run Code Online (Sandbox Code Playgroud)

即使对象具有多个具有相同值的属性(与上面的其他一些答案不同),此版本也能正常工作,并且当您到达此处时,Visual Studio 等编辑器将为属性名称提供智能感知: nameof(obj, x => x.