2010-06-06 64 views
1

是否有可能訪問只能在「with」語句內使用方括號表示法訪問的對象屬性。「與」範圍和屬性用方括號表示法

例子:

var o = { "bad-property": 1, "another:bad:property": 2, "goodProperty": 3 }; 

with(o) { 
    console.log(goodProperty); // works awesome 
    console.log(???) // how to access "bad:property"? 
} 
+1

停止使用'with',請 – 2010-06-06 21:59:05

+2

''有它的用途,就像'goto'或'eval'一樣。我認爲通用[認爲有害](http://en.wikipedia.org/wiki/Considered_harmful)聲明比有問題的聲明更有害。 – Anurag 2010-06-06 22:06:54

+0

@ M28我同意Anurag,JavaScript的美麗之一是它的多功能性。請參閱此帖http://stackoverflow.com/questions/61552/are-there-legitimate-uses-for-javascripts-with-statement。雖然它確實有它的危險。 'Javascript:道格拉斯克羅克福德的好作品'中的 – Laramie 2010-06-06 22:17:19

回答

2

哇這是舊的,但在這裏的答案是錯誤的,實際上有辦法完全按照你的要求。

with({'[email protected]#$%': 'omg', d: 'hai'}) { 
    console.log(d); //hai - naturally 
    console.log(valueOf()['[email protected]#$%']); //omg - OMG 
} 

你看到了嗎? valueOf()是魔術字。它返回其父對象的原始值,或者如果該對象沒有原始值,則返回該對象本身。每個對象和對象類型的基元都會繼承此方法,因爲它是Object.prototype中的內置屬性。所以...你去了。

+0

它有點晚了,但是感謝'valueOf'。這徹底解決了這個問題。 – Anurag 2011-02-21 08:29:44

0

據我瞭解有(O)基本上是跳轉到0的範圍,所以性能是由它們的名字進行訪問:「壞」及「goodProperty」。

with(o) { 
    bad="new value"; 
    goodProperty=22; 
} 
+1

問題是,如何訪問他們的名字無法訪問的屬性(憑藉他們的名字)。 – 2010-06-06 22:00:59

+0

我添加了一個令人困惑的屬性名稱。 ''bad:property「'是屬性的名稱(它可能同樣是''bad-property'''),但我不知道它是否可以在scope內部訪問。一種解決方案是規範化屬性名稱並將''bad:property''更改爲''badProperty''',但我希望避免這種情況,因爲在某些情況下可能不可能。 – Anurag 2010-06-06 22:01:02

1

通常,with關鍵字用於解析長名稱空間,而不是單個對象引用。我想我需要知道在這裏使用關鍵字的意圖是什麼。我不相信語法分析器會讓你脫離o.bad:property,這基本上是用什麼編碼的。

如果o對象的例子只是一個快捷方式到一個較長的命名空間,我的建議是使用阻止一個對象短決議,然後把盒子你的財產到像這樣的字符串...

var nmSpace = new Object(); 
nmSpace.o = { "bad:property": 1, "goodProperty": 2 }; 

with (nmSpace) { 
    alert(o['goodProperty']); // works awesome 
    alert(o['bad:property']); // now accesses "bad:property"! 
} 

希望有幫助。

+0

它正在模板中使用[JR的小型圖書館](http://ejohn.org/blog/javascript-micro-templating/)。數據來自外部來源,我將相關根對象傳遞給填充它的模板引擎。如果不拆開模板,我不能任意打斷對象鏈。 – Anurag 2010-06-06 22:15:45

+0

明白了。如果你不能影響字符串的模板來限定屬性名稱,我的猜測是你必須通過正則表達式規範屬性名稱來避免語法違規。 – Laramie 2010-06-06 22:43:23

+0

訪問這些值的唯一方法是通過帶引號的標識符 - o ['bad-property']和o ['bad:property']仍然有效。這可以在'with'內工作(儘管此時你不需要使用它)。而道具仍然可以通過for(var s in o){}。如果你的模板引擎需要一個與你的對象的屬性名完全匹配的變量名,我認爲你不可能沒有,正如你已經提到的,規範化所有的東西。 – Andrew 2010-06-07 00:13:19