Переменная JavaScript и одна и та же переменная также являются объектами - программирование
Подтвердить что ты не робот

Переменная JavaScript и одна и та же переменная также являются объектами

Я немного новичок в 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);

Таким образом, вы можете объявить переменную и также иметь ту же переменную, что и объект. Очевидно, это не могло быть сделано с тем, что я сделал, но вы получите картину.

Любая помощь будет очень признательна!

4b9b3361

Ответ 1

Собственно, вы можете.

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

Ответ 2

Переменные JavaScript могут содержать либо объекты, либо примитивы. Если у вас есть объект, вы можете установить на него свойства (подпеременные), если у вас есть примитив, вы не можете.

Вернемся к вашему примеру, Строки JavaScript могут быть либо примитивными, либо объектами, в зависимости от того, как вы его определяете, и сделать больше запутанный, примитив будет временно преобразован в объект при попытке получить доступ к его свойствам.

Следующий код отобразит "bar", так как наша строка специально объявлена ​​как объект String с ключевым словом new:

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

Если мы удалим часть new String, вместо нее получим примитив. JavaScript преобразует его для нас, когда мы пытаемся установить foo, но ничего не сохраняется, так как это действительно просто примитив под ним, и мы возвращаем результат "undefined", когда вызываем alert(b.foo):

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

Это всего лишь одна из многих вещей, которые запутывают встроенные типы JavaScript, я рекомендую прочитать раздел раздел "Глобальные объекты" в JavaScript Javascript для всех подробностей.

Ответ 3

Колинк абсолютно прав в том смысле, что до тех пор, пока вы ожидаете, что значение будет строкой, вы можете "вставить" значение в объект, а затем переопределить 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, это a 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; }
};

Ответ 4

Вы можете сделать это, создав новый объект и расширив прототип 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);

Ответ 5

Фактически "Hello World" является строковым литералом (typeof "Hello World" === "string"), а не экземпляром ничего.

Вы можете создать

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

и теперь typeof s === "object", instanceof String и Object.

Объект String также может иметь дополнительные свойства, например

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

То, что вам действительно нужно, скорее всего, ответы других;)

Ответ 6

Пока ваша переменная не является примитивом, вы можете добавить к ней свойства.

В вашем случае

var msg = "Hello World";

msg является примитивной переменной, поэтому вы не можете достичь того, чего хотите. Но вы можете создать реальный String object и добавить его свойства.

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