我有一个具有 String对象:
的属性的对象public class AccountListTest extends JFrame implements ActionListener{
public JComboBox combo;
AccountListTest()
{
JFrame myframe = new JFrame();
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mypanel = new JPanel();
String [] country = {"USA","Ireland"};
//JComboBox combo = new JComboBox();
myframe.setSize(450,300);
combo = new JComboBox(country);
combo.addActionListener(this);
mypanel.add(combo , BorderLayout.PAGE_END);
myframe.add(mypanel);
myframe.setVisible(true);
AddressFactory afactory = new AddressFactory();
//afactory.getAccountList(USA).display();
//afactory.getAccountList(Ireland).display();
combo.addActionListener(this);
myframe.add(mypanel);
myframe.setVisible(true);
}
public static void main (String[] args)
{
new AccountListTest();
}
public void actionPerformed(ActionEvent e) {
Object originator = e.getSource();
if(e.getActionCommand().equals("USA"))
{
System.exit(0);
}
else if(e.getActionCommand().equals("Ireland"))
{
System.out.println("IRL SEL");
}
// TODO Auto-generated method stub
}
}
我正在使用字符串对象,因为我需要在对象上存储其他子属性,同时仍然能够获取字符串值:
var obj = {
foo: new String("bar")
};
我觉得愚蠢但是如何更新String对象的值?好像可能需要应用一些Array splice magic。
编辑:为了清楚起见,我理解JS中的字符串原语和其中的不变性。这是我正在谈论的一个对象。这是需要通过的测试:
obj.foo.baz = "baz";
"" + obj.foo; //-> "bar";
答案 0 :(得分:2)
您需要创建一个新的String对象,并将任何新属性和值扩展到该String对象。我在下面提供了一个简单的例子。也就是说,可以修改此示例以满足您的目的(您可以创建自定义扩展或 setter 功能)。
var createNewString = function (oldStringObj, string) {
var _new = new String(string);
var keys = Object.keys(oldStringObj); // returns only custom properties (not part of prototype)
for (var i=0,n=keys.length; i<n; i++){
var key = keys[i];
if (Number.isInteger(+key)) {
continue; // skip property if it's a numbered key
}
_new[key] = oldStringObj[key]; // simple assignment (not a deep copy) -- room for improvement
}
return _new;
};
var obj = {
foo: new String("bar")
};
obj.foo.baz = "baz"; // new property
obj.foo = createNewString( obj.foo, 'foot' );
//obj.foo=='foot' and obj.foo.baz=='baz'
答案 1 :(得分:2)
你不能。无论你如何构建&#34;字符串都是不可改变的。他们(文字或对象)。
你应该做的只是使用一个实际的对象来保存你的值和你的字符串。
在最基本的层面上,这将是:
var obj = {
foo: "bar"
};
// later...
obj.baz = "baz";
"" + obj.foo; //-> "bar";
你也可以考虑使用monadic类型作为&#34;放大器&#34; / decorator,但这个用例似乎有些过分。
作为旁注,添加属性和&#34;随机&#34;函数到字符串对象不是一个好的OOP选择。这些与字符串的值严格无关,只对更高级别的对象有意义,这是它们应该驻留的位置。
答案 2 :(得分:1)
我建议您使用自定义类型,而不是默认的String类型。 ES6规范定义了String对象的基础值存储在其#34; [[StringData]]内部插槽&#34;中。分配此插槽的唯一位置是通过new String
构造函数,因此它是隐式不可变的。您可以创建一个新类型,它具有您需要的类似字符串的行为,同时是可变的。
class MutableString {
constructor(value) {
this.value = value;
}
toString() {
return this.value;
}
}
var obj = {
foo: new MutableString('bar')
};
obj.foo.baz = "baz";
console.assert("" + obj.foo == "bar");
console.assert(obj.foo + "" == "bar");
console.assert(obj.foo.baz == "baz");
console.assert(Object.keys({[obj.foo]: 1})[0] == "bar");
obj.foo.value = "foooooo";
console.assert("" + obj.foo == "foooooo");
console.assert(obj.foo + "" == "foooooo");
console.assert(obj.foo.baz == "baz");
console.assert(Object.keys({[obj.foo]: 1})[0] == "foooooo");
因为它不是真正的字符串,所以它不支持任何字符串方法,因此它可能不适合您的使用。但它更灵活,更清晰,所以我建议尽可能考虑它。
可能需要定义一个valueOf()
方法,例如toString()
来处理其他一些案例,但我还没有得到验证。