【问题标题】:JavaScript variable and the same variable also be an objectJavaScript 变量和同一个变量也是一个对象
【发布时间】:2012-12-29 02:23:56
【问题描述】:

我对 JavaScript 有点陌生,我有一个问题。

我知道您可以设置变量和“子变量”。喜欢:

var msg = "Hello World";
alert(msg);

还有

var msg = {
    lipsum: "Lorem Ipsum Dolor Sit Amet"
}
alert(msg.lipsum);

但我想知道你是否可以两者都做,比如

var msg = "Hello World" || {
    lipsum: "Lorem Ipsum"
}
alert(msg + msg.lipsum);

这样,您可以声明一个变量,也可以将同一个变量作为一个对象。显然,我所做的无法做到这一点,但你明白了。

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript arrays variables object


    【解决方案1】:

    其实可以的。

    var msg = {
        lipsum: "Lorem Ipsum",
        toString: function() {return "Hello World!"}
    };
    

    【讨论】:

    • 真的吗?而且我不必这样做alert(msg.toString())
    • 不,因为alert 需要一个字符串,所以它会尝试通过调用其toString 方法将你给它的任何内容转换为一个字符串。
    • 我会注意到,当你这样做时,你真的没有保持同样的心态。您只是在制作一个对象(仍然)并覆盖它是如何转换为字符串的。它有效吗?绝对地。只是它不再是一个简单的字符串。如果您尝试使用var foo = msg + 10;,您将很难将msg 用作数字。
    • +1.. 优秀的解决方案.. @ModernDesigner.. 检查这个小提琴jsfiddle.net/sushanth009/eZSAV
    • 酷!谢谢!这就是我想知道的。
    【解决方案2】:

    您可以通过创建一个新对象并扩展原型toString() 方法来实现。类似的东西应该可以工作:

    function Msg() {
        this.message = 'some message';
        this.lipsum = 'lipsum';
    }
    
    Msg.prototype.toString = function() {
        return this.message;
    }
    
    var msg = new Msg();
    
    alert(msg + msg.lipsum);
    

    【讨论】:

      【解决方案3】:

      实际上"Hello World" 是一个字符串文字 (typeof "Hello World" === "string"),而不是任何东西的实例。

      你可以创建一个

      var s = new String("Hello World");
      

      现在是typeof s === "object"instanceof StringObject

      字符串对象也可以有额外的属性,比如

      s.hint = "!";
      // console.log(s + s.hint) prints "Hello World!" into console
      

      你真正需要的很可能是其他人回答的;)

      【讨论】:

        【解决方案4】:

        只要您的变量不是primitive,您就可以为其添加属性。

        你的情况

        var msg = "Hello World";
        

        msg 是一个原始变量,所以你无法实现你想要的。 但你可以创建一个真正的String object 并为其添加属性。

        var msg = new String("Hello World");
        msg.lipsum = "lipsum";
        alert(msg + msg.lipsum);
        

        【讨论】:

          【解决方案5】:

          JavaScript 变量可以包含对象或原语。如果你有一个对象,你可以在它上面设置属性(子变量),如果你有一个基元,你就不能。

          回到你的例子,JavaScript Strings 可以是一个基元也可以是一个对象,这取决于你如何定义它,为了让事情更混乱,当你尝试访问它的属性时,一个基元将被临时转换为一个对象.

          下面的代码会显示“bar”,因为我们的字符串是用new关键字明确声明为String对象的:

          a = new String("Hello World");
          a.foo = "bar";
          alert(a.foo);
          

          如果我们删除new String 部分,我们会得到一个原语。当我们尝试设置 foo 时,JavaScript 会为我们转换它,但什么都没有保存,因为它实际上只是下面的一个原语,当我们调用 alert(b.foo) 时,我们会返回结果“未定义”:

          b = "Hello World";
          b.foo = "bar";
          alert(b.foo);
          

          这只是内置 JavaScript 类型令人困惑的众多事情之一,我建议您通读 Mozilla Javascript Reference's Global Objects section 以了解所有血腥细节。

          【讨论】:

            【解决方案6】:

            Kolink 是绝对正确的,只要您希望该值是一个字符串,那么您可以将值“装箱”到一个对象中,然后覆盖 toString 方法。但是,所做的只是允许javascript(当它需要将对象输出为字符串时)输出变量(通过为您本机调用toString)。它不是返回原始值,而是一个装在另一个对象中的值。

            我想指出几件事情,以说明两者的差异(举几个例子)。所以,让我们来看看以下内容:

            var BoxedString = {
              value: 'Hello, world!',
              toString: function(){ return this.value; }
            };
            var BoxedNumber = {
              value: 3.14,
              toString: function(){ return this.value; }
            };
            var BoxedDate = {
              value: new Date(), // today
              toString: function(){ return this.value; }
            };
            

            很简单,我们可以在必要时将这些中的每一个输出为字符串(或者我们可以吗?)

            // Each of these implicitly calls `.toString()` because we're concatenating
            // them within another string. Metho calls (like `alert()` that look for a 
            // string result have the same effect.
            console.log('BoxedString: '+BoxedString); // BoxedString: Hello, world!
            console.log('BoxedNumber: '+BoxedNumber); // BoxedNumber: 3.14
            console.log('BoxedDate:   '+BoxedDate);   // fail!
            

            等等,BoxedDate 失败;这是为什么?因为我们的toString 正在返回Date 对象,并且不能按原样输出。但是,如果我们将BoxedDate.toString 更改为返回this.value.toString(),我们会看到更好的结果(继续尝试,我会等待。)

            让我们坚持BoxedDate 趋势并尝试日期方法:

            console.log(BoxedDate.getFullYear()); // BoxedDate.getFullYear is not a function
            

            再一次,它实际上不是Date,而是包裹在闪亮盒子中的Date。奇怪的是,Javascript 知道的足够隐式转换 BoxedNumber

            var sum = 38.86 + BoxedNumber; // 42 (works)
            

            但是,不要尝试任何Number 对象方法,例如toFixed()。与BoxedString.replace()toUpperCase() 等字符串方法相同。

            不过,如果我要在 @Kolink 的答案中添加一些内容,则还应包括 valueOf 作为对象声明的一部分。比如:

            var BoxedValue = {
              value: 2013,
              toString: function(){ return this.value.toString(); }
              valueOf: function(){ return this.value; }
            };
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-22
              • 2011-08-31
              • 2011-11-26
              • 2021-03-21
              • 2017-12-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多