如何在JavaScript中设置/更新String对象的值

时间:2016-02-16 21:31:55

标签: javascript

我有一个具有 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";

3 个答案:

答案 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()来处理其他一些案例,但我还没有得到验证。