JavaScript变量和相同的变量也是一个对象

时间:2013-01-15 02:05:40

标签: javascript arrays variables object

我对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);

这样,您可以声明一个变量,并将同一个变量作为一个对象。显然,我无法完成所做的事情,但是你得到了这张照片。

非常感谢任何帮助!

6 个答案:

答案 0 :(得分:20)

实际上,你可以。

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

答案 1 :(得分:12)

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

回到您的示例,JavaScript Strings可以是基元或对象,具体取决于您如何定义它,并使问题更加混乱,当您尝试访问时,基元将临时转换为对象它的属性。

以下代码将显示“bar”,因为我们的字符串被特别声明为带有new关键字的String对象:

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

如果我们删除new String部分,我们会得到一个原语。当我们尝试设置foo时,JavaScript会将它转换为我们,但没有任何内容会被保存,因为它实际上只是一个原语,当我们调用alert(b.foo)时,我们会返回结果“undefined”:

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

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

答案 2 :(得分: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; }
};

答案 3 :(得分: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);

答案 4 :(得分:1)

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

你可以创建一个

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

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

String对象还可以具有其他属性,例如

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

你真正需要的是其他人所回答的内容;)

答案 5 :(得分:1)

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

在你的情况下

var msg = "Hello World";

msg是一个原始变量,因此无法达到您想要的效果。 但您可以创建一个真实的String object并添加它属性。

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