2012-11-28 139 views
23

是否有可能得到的對象屬性的字符串名字獲取對象屬性的字符串名字

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

我想用這樣的:

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' 

謝謝你在先進

注意:這段代碼正是我要找的。我明白這聽起來很愚蠢,但事實並非如此。

這就是我想要做的。

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

---------------------- 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' 

DEMO:http://jsbin.com/iyabal/1/edit

+7

我很困惑......爲什麼要讓屬性名稱返回與您餵食的食物相同的東西?您已經知道屬性名稱,然後...如果您正在尋找通過屬性進行迭代的方式,則可以使用括號表示法並循環通過鍵,因爲屬性也是散列索引 – RonaldBarzell

+0

您還需要將引用傳遞給將對象放入函數中。 –

+0

不自動。由'country'屬性引用的字符串不知道任何有關'address'對象的信息,而'address'屬性引用的對象不知道有關'person'對象的任何信息。 –

回答

2

當然可以,只要稍微改變。

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

現在你可以得到的價值,像這樣:

var pn = propName(person,person.first_name); 
// pn = "first_name"; 

注意我不知道它可以用於。

其他注意事項不適合嵌套對象。但是再次看到第一個音符。

+9

這假定沒有兩個屬性在對象中具有相同的值。 – Sampson

+0

...並不足以嵌套對象。 – Christophe

+0

它只能深入一層。 – Ivan

0

不,這是不可能的。

想象一下:

person.age = 42; 
person.favoriteNumber = 42; 

var pn = propName(person.age) 
// == propName(42) 
// == propName(person.favoriteNumber); 

屬性名稱的參考僅僅是失去了在這一進程。

+1

爲什麼downvote ?任何反駁? –

0

您可以爲該對象創建一個名稱間距方法。該方法需要對對象進行變異,以便字符串變爲對象,而不是保存兩個屬性,分別爲value_namespace

DEMO:http://jsfiddle.net/y4Y8p/1/

var namespace = function(root, name) { 
    root._namespace = name; 
    function ns(obj) { 
     for(var i in obj) { 
      var a = obj._namespace.split('.') 
      if (a.length) { 
       a.push(i); 
      } 
      if(typeof obj[i] == 'object') { 
       obj[i]._namespace = a.join('.'); 
       ns(obj[i]); 
       return; 
      } 
      if(typeof obj[i] == 'string') { 
       var str = obj[i].toString(); 
       obj[i] = { 
        _namespace: a.join('.'), 
        value: str 
       }; 
      } 
     } 
    } 
    ns(root); 
}; 

namespace(person, 'person'); 

console.log(person.address.street._namespace) // person.address.street 
console.log(person.address.street.value) // 'Factory 1' 

所以現在你可以這樣做:

var o = { message: MSG_ACTION }; 
o[ person.first_name._namespace ] = person.first_name.value; 

extPort.postMessage(o); 
+0

我對這個答案很着迷,所以我開始竊取它,試圖找到一個更清潔的方法。這是我到目前爲止,你認爲什麼:http://jsfiddle.net/y4Y8p/17/ –

+0

@JasonSperske很好,但它不是遞歸的,所以它只能工作3級深:http:// jsfiddle.net/y4Y8p/18/ – David

+0

http://jsfiddle.net/y4Y8p/22/現在就試試:)還有更大的問題,如需要所有值並將它們轉換爲字符串,但這是一個有趣的位代碼玩 –

3

您可以在一個功能包裝你的財產,那麼函數轉換爲字符串,並獲得地產出的。

例如:

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

然後使用它:

var myObj = { 
    myProperty: "testing" 
}; 

getPropertyName(function() { myObj.myProperty; }); // myProperty 

它看起來與ES6語法更好一點:

getPropertyName(() => myObj.myProperty); 

雖然我不是100%確定那會返回一個function() { ... }像字符串。我只是通過一個轉譯器來使用它。

+4

只要小心使用此與minifaction ... –

+0

偉大..它幫助我..謝謝 –

12

我知道使用Object.keys(your_object)的最佳做法。它會解析爲您的數組屬性名稱。例如:

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

我希望這個例子對你有用。

+5

應該是小寫的'鑰匙'。 – madprops

0

我處於同樣的情況。

這是你的方式得到它使用LodashUnderScore的庫,與值的一個限制是唯一的:

var myObject = { 
'a': 1, 
'b': 2, 
'c': 3 
} 
_.findKey(myObject, function(curValue) { return myObject.a === curValue }); 

普通的JavaScript

function getPropAsString(source, value){ 
    var keys = Object.keys(source); 

    var curIndex, 
     total, 
     foundKey; 

    for(curIndex = 0, total = keys.length; curIndex < total; curIndex++){ 
     var curKey = keys[ curIndex ]; 
     if (source[ curKey ] === value){ 
      foundKey = curKey; 
      break; 
     } 
    } 

    return foundKey; 
} 

var myObject = { 
'a': 1, 
'b': 2, 
'c': 3 
} 
getPropAsString(myObject, myObject.a) 

但是,我更願意修復該代碼作爲解決方案。舉例:

var myObject = { 
'a': {key:'a', value:1}, 
'b': {key:'b', value:2}, 
'c': {key:'c', value:3} 
} 

console.log(myObject.a.key) 
0

有辦法通過使用閉包來完成。使用ES6語法的示例

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' 
相關問題