Javascript.RU

Базовые типы: Строки, Числа, Boolean

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/types-intro.

В этой статье собраны особенности базовых типов данных, которые важны для программистов из других областей.

В Javascript есть и объектные типы данных и элементарные, которые можно интерпретировать как объекты.

типы данных

Элементарные - создаются простым указанием данных:

var orange = "Апельсин"

Объектные - например, через оператор new:

var orange = new String("Апельсин")

На практике, хотя для каждого элементарного типа есть соответствующий объект, использовать их не рекомендуется. Это - отмершая часть языка.

var ok = new Boolean(true) // не надо

Элементарные типы автоматически интерпретируются как объекты при вызовах методов, поэтому можно, определять длину строки как:

alert("Апельсин".length)

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

Например, typeof выдаст разный результат:

alert(typeof "test")
alert(typeof new String("test"))

Это - еще одна причина избегать использования объектов там, где существует элементарный тип: меньше путаницы.

Преобразование типа можно явным образом сделать через его название:

var test = Boolean("something") // true

Кроме всем известных типов данных - в javascript есть специальное значение undefined, которое, условно говоря, обозначает что "данных нет". Не null, а данных нет. Понимайте как хотите.

Далее рассмотрим особенности каждого из этих типов.

Все числа хранятся в формате float64, т.е 8 байт с плавающей точкой. В этом формате не всегда возможны точные вычисления.

Например,

alert(0.1+0.2)  // выведет не 0.3!

При операциях с Number - никогда не происходят ошибки. Зато могут быть возвращены специальные значения:

1/0
Number.POSITIVE_INFINITY (плюс бесконечность)
-1/0
Number.NEGATIVE_INFINITY (минус бесконечность)
Number(“something”)
NaN (Not-a-Number, результат ошибочной операции)

Бесконечность бывает полезно использовать в обычном коде. Например, положительная бесконечность Number.POSITIVE_INFINITY больше любого Number, и даже больше самой себя.

NaN - особый результат.

  • Любая математическая операция с NaN дает NaN:
    • NaN + 1 = NaN
  • NaN не равен сам себе:
    • NaN == NaN // false
  • Можно проверить с помощью функции isNaN:
    • isNaN(NaN) // true

Для этого используется метод toFixed.

0.1234.toFixed(2)  = 0.12

Стандартно конвертация осуществляется вызовом Number(). Можно и попроще: +str.

// эквивалентные записи
var str = "002"
var a = Number(str) // 2
// нечисла превращаются в NaN
+"0.1"  // => 0.1
+"0.1z" // => Number.NaN

Кроме жесткой конвертации есть и более мягкая фильтрация в число:

// обрезается все после числа
parseFloat("0.1zf") = 0.1
parseInt("08f.4", 10) = 8
// тут числа вообще нет, поэтому NaN
parseFloat("smth") = Number.NaN

parseFloat , parseInt переводят слева направо, пока это возможно. Если вообще невозможно - то NaN.

Второй аргумент parseInt - основание системы счисления. Если его нет, то система сама пытается угадать систему счисления:

parseInt("0x10") = 16 // т.к 0x обозначает 16-ричную систему
parseInt("010") = 8 // т.к ведущий 0 обозначает 8-ричную систему
// если хотите без сюрпризов - указывайте основание явно
parseInt("010",10) = 10

Все математические функции находятся в "пакете" Math. Не то, чтобы в javascript есть реальные пакеты, просто так получилось.

  • Math.floor() / Math.round() / Math.ceil() - округление
  • Math.abs() - модуль числа
  • Math.sin() и т.д

Строки в javascript - полностью юникодные.

  • Кавычки двойные и одинарные работают одинаково
  • Можно указывать юникодные символы через \uXXXX:
    • "звездочка:\u002a"
  • Встроены регулярные выражения, методы replace/match:
    • "превед медвед".replace(/(.*?)\s(.*)/, "$2, $1!") // => медвед, превед!

Как это обычно и бывает, в регулярках символ \w обозначает латинские буквоцифры или подчеркивание, но не русские буквы.

Длина строки хранится в свойстве length.

В javascript - особый список значений, которые при приведении к Boolean становятся false. Он отличается, например, от аналогичного списка в PHP.

False
false
null
undefined
“”
0
Number.NaN
True – все остальное
“0”
“false”

Чтобы привести значение к булевому - используется либо явное указание типа: Boolean(a), либо двойное отрицание: !!a

Boolean(a) == !!a

Автор: Kollega (не зарегистрирован), дата: 30 июля, 2008 - 10:45
#permalink

По поводу строчки "Все числа хранятся в формате double word, т.е 8 байт. В этом формате невозможны точные вычисления." под загаловком "Number\Неточные вычисления" есть пара замечаний: word (и double word, соответственно) не предполагает возможности хранить дробные и отрицательные числа, только положительные целые в любом языке программирования, и предполагает только точные вычисления... А тут, судя по всему, используется real64 - восьмибайтная вещественная переменная, в которой значение каждого бита далеко не так очевидно как в целочисленных...


Автор: Илья Кантор, дата: 30 июля, 2008 - 14:08
#permalink

Да, float64. Поправлено. Вот выдержка из исходников SpiderMonkey с точным определением типа:

js/src/jspubtd.h
[c]
typedef uint16 jschar;
typedef int32 jsint;
typedef uint32 jsuint;
typedef float64 jsdouble; // оно
typedef jsword jsval;
typedef jsword jsid;
[/c]


Автор: Гость (не зарегистрирован), дата: 30 апреля, 2009 - 02:34
#permalink

Собственно, double word = 4 байта


Автор: Гость (не зарегистрирован), дата: 15 июля, 2009 - 11:07
#permalink

Собственно, word - это машинное слово, и его длина равна разрядности машины


Автор: Дзен-трансгуманист, дата: 19 июня, 2012 - 07:44
#permalink

А вот на всеми нами горячо любимой архитектуре x86 (внезапно, да?) word всегда считался равным 16 битам. И кто тут, спрашивается, врет: правило или системные хедеры?


Автор: Infocatcher (не зарегистрирован), дата: 10 октября, 2008 - 03:43
#permalink

Еще есть такая полезная штука, как Number.toFixed.

var n = 0.123456789.toFixed(6);
alert(n); // 0.123457
alert(typeof n); // "string"

А вот IE 5.0 (уже к счастью почти совсем не актуальный) такого не умеет...


Автор: dbersten (не зарегистрирован), дата: 21 мая, 2010 - 22:49
#permalink

Кстати, в хроме эта функция тоже не работает - ничего не выводится. Хотя тот же файл в мозилле работает корректно, и ошибки не выдаются.


Автор: Гость (не зарегистрирован), дата: 28 июня, 2010 - 10:24
#permalink

У меня в хроме получилось сделать так:

(new Number(1.11111111)).toFixed(4)

Автор: MortaLity (не зарегистрирован), дата: 14 мая, 2009 - 10:11
#permalink

Infocatcher, voobshe to .toFixed bilo ypom9nyto v etoj statje vnimatelnee nado 4itat =)


Автор: Minh (не зарегистрирован), дата: 17 мая, 2009 - 17:58
#permalink

Не объясните подробнее что делает ваше выражение:

"превед медвед".replace(/(.*?)\s(.*)/, "$2, $1!") // => медвед, превед!

Спасибо


Автор: Гость (не зарегистрирован), дата: 19 мая, 2009 - 12:24
#permalink

присоединяюсь к Minh. Поясните, плз.


Автор: Илья Кантор, дата: 19 мая, 2009 - 14:39
#permalink

Этот вызов захватит в первую скобку слово "превед", а во вторую - "медвед", затем заменит их на $2, $1 - то есть, на "медвед, превед".

Более подробно про регулярные выражения вы можете прочитать в статье
Регулярные выражения.


Автор: Гость (не зарегистрирован), дата: 13 июня, 2009 - 22:21
#permalink
alert(0.1+0.2);

Результат: 0.3000000004... Это как?


Автор: Гость (не зарегистрирован), дата: 28 сентября, 2009 - 17:09
#permalink

В памяти машины все вещественные числа хранятся в определенном количестве байт, и из-за кратности значения всегда существует неточность между вводимым значением (тем что мы используем в коде) и тем что находится в памяти.

Подробнее на wiki или в google на тему хранение данных в памяти компьютера.


Автор: Гость (не зарегистрирован), дата: 28 июня, 2010 - 10:26
#permalink

Гораздо интереснее, как это обойти
Есть рецепты?


Автор: Гость (не зарегистрирован), дата: 5 июля, 2010 - 15:21
#permalink

Единственный реальный вариант:
1) округлять до разумного кол-ва знаков после запятой
Принципиальное решение:
2) отказаться от дробных чисел
Или:
3) отказаться от математики на клиенте. В PHP есть библиотека BCMath в которой можно считать с произвольной точностью. Принцип - отказ от двоичной системы и вычисления на основе представления чисел как последовательности символов по алгоритмам сложения и т.п. в столбик.


Автор: blessmaster, дата: 9 января, 2011 - 05:34
#permalink

Ради клиентских вычислений напрягать сервер - дороговато будет, если это не сложная математика, а 0,1+0,2 )))

Есть такой вариант http://sourceforge.net/projects/bcmath-js/ - пока ещё не использовал, но планирую в скорости опробовать


Автор: Гость (не зарегистрирован), дата: 3 января, 2012 - 14:36
#permalink

А есть ещё такой вариант: (1+2)/10


Автор: opus, дата: 27 сентября, 2009 - 16:49
#permalink

var test = Boolean("something") // true

Почему true, а не false?


Автор: Гость (не зарегистрирован), дата: 28 сентября, 2009 - 16:58
#permalink

Перечитайте, пожалуйста еще раз статью.

А вообще все грубо говоря "ненулевые элементы", точнее элементы имеющие значение отличное от:
false
null
undefined
“”
0
Number.NaN

имеют значение true

Это сделали для вашего же удобства.


Автор: blessmaster, дата: 9 января, 2011 - 05:37
#permalink

Чтобы можно было кратко писать

if (mystr) { ... }

Подразумевая: "если в mystr что-то есть"


Автор: Юрий Федоров, дата: 25 июня, 2014 - 02:24
#permalink

Даже в случае:
var res=Boolen("false")//true
В случае:
var res=Boolen('''')//false
(любая непустая строка-true)


Автор: opus, дата: 27 сентября, 2009 - 18:50
#permalink

Заранее спасибо!


Автор: opus, дата: 27 сентября, 2009 - 19:35
#permalink

Как это обычно и бывает, в регулярках символ \w обозначает латинские буквоцифры или подчеркивание, но не русские буквы.

Вы не поясните что вы имели в виду? А то знаете, все слова понятны, но ничего не понятно


Автор: Гость (не зарегистрирован), дата: 28 сентября, 2009 - 17:00
#permalink

прогуглите "Регулярные выражения" для понимания смысла данных слов. довольно полная информация также присутствует на wiki.


Автор: proxima (не зарегистрирован), дата: 9 декабря, 2009 - 12:50
#permalink

Интересная статья, много полезных мелочей, которые нельзя узнать, изучая язык по чужим скриптам и примерам =).


Автор: Гость (не зарегистрирован), дата: 11 декабря, 2009 - 15:45
#permalink

скажите, от куда parseInt("010") = 8 //
восемь? 010 - это два в 2х ричной системе


Автор: B@rmaley.e><e (не зарегистрирован), дата: 11 декабря, 2009 - 19:25
#permalink

А кто говорил про двоичную? Речь идет о восьмеричной.


Автор: puppy (не зарегистрирован), дата: 18 февраля, 2010 - 17:34
#permalink

Не совсем корректный рисунок, т.к. Number, Boolean и String это объекты-обертки, простые типы именуются с маленькой буквы: т.е. соответственно number, boolean, string.


Автор: Гость (не зарегистрирован), дата: 12 октября, 2010 - 09:18
#permalink

По результатам операции typeof для null или undefined можно заключить, что это не элементарные типы, а объектные, так как результат выводится как object. Смею предположить, что интерпретатор при анализе выражения, например var n = null, невидимым образом создает объект, согласно литералу null, как это делается в Java. Поэтому на мой взгляд элементарных типов три: number, boolean и string. Если не прав, то поправьте меня:)


Автор: blessmaster, дата: 9 января, 2011 - 05:42
#permalink

null и undefined - это "значения", а не типы. Соответственно у значений тип есть, но он ни string, ни boolean, ни number. Конечно, хорошо бы перечитать спецификацию ECMA на эту тему, но замечу, что реализации - по-разному "хромают" на эту тему.


Автор: Гость (не зарегистрирован), дата: 12 октября, 2010 - 09:20
#permalink

Здравствуйте, как проверить, что Number.POSITIVE_INFINITY больше самого себя например? Если пишу if (Number.POSITIVE_INFINITY == 1/0) ... или, например, if (1/0 == 2/0) ..., то результат true.


Автор: blessmaster, дата: 9 января, 2011 - 05:47
#permalink

Что означает "больше самого себя"? Это как?

Деления любого числа на ноль даёт в результате значение Number.POSITIVE_INFINITY. Разумеется, оно всегда будет равно само себе, так же как сравнивать бесконечности - бессмысленно по определению.


Автор: Гость (не зарегистрирован), дата: 27 марта, 2011 - 16:07
#permalink

А там в статье так написано


Автор: Гость (не зарегистрирован), дата: 28 января, 2011 - 13:07
#permalink

Статьи интересные. Но мне кажеться, что было бы неплохо к каждой статье подготовить практические задания. Что бы на практике закрепить пройденный материал. И правильные решения где-то показывать.


Автор: Гость (не зарегистрирован), дата: 6 февраля, 2011 - 01:25
#permalink

Уважаемый, а про date не забыли?


Автор: Гость (не зарегистрирован), дата: 19 апреля, 2011 - 17:08
#permalink

Здравстуйте помогите пожалуйста!Ввожу 100 выводит слово ошибка.Что не так вот код
var pricePattern = "^[0-9]*$";
var errorMessage = "";
function checkPrice(price)
{
if(!price.match(pricePattern)) {
alert("ошибка");
errorMessage +="*" + errorPrice + "\n";
}
}


Автор: B@rmaley.e><e, дата: 20 апреля, 2011 - 22:02
#permalink

Думаю, стоит почитать о регулярных выражениях в JavaScript.


Автор: Гость (не зарегистрирован), дата: 17 октября, 2011 - 15:03
#permalink
var pricePattern = "^[0-9]*$";
var errorMessage = "";
function checkPrice(price){


    // привести к строке необходимо
    if(typeof price!="string" )
         price = (price).toString()



    if(!price.match(pricePattern)) {
        alert("ошибка");
        errorMessage +="*" + errorPrice + "\n";
    }
}
checkPrice(100)

Автор: Гость (не зарегистрирован), дата: 15 июля, 2011 - 15:08
#permalink

Запускаю в хроме:

alert(typeof false);
var status=false;
alert(typeof status);

Получаю сначала "boolean", потом "string". Почему так?


Автор: Гость (не зарегистрирован), дата: 15 июля, 2011 - 15:22
#permalink

Кстати, в firefox у меня такого не наблюдается - выводится оба раза boolean.


Автор: Гость (не зарегистрирован), дата: 18 июля, 2011 - 10:43
#permalink

Сам себе отвечаю. Так как код в глобальном контексте, то var status означает window.status (статусная строка в браузере, которая всегда string).


Автор: Гость (не зарегистрирован), дата: 19 сентября, 2011 - 11:50
#permalink

Как все же правильно парсить строку "True" в булево значение?


Автор: Гость (не зарегистрирован), дата: 17 октября, 2011 - 15:05
#permalink
!!"True"

Автор: melky, дата: 21 декабря, 2011 - 10:11
#permalink

а "false" ?

если регистр всегда будет таким - т.е. всегда будет начинаться с большой буквы, то так :

var boolka = "True";
var boolka_bool = boolka == "True"; // true.

Автор: Дзен-трансгуманист, дата: 19 июня, 2012 - 10:22
#permalink
function parseBool(str) {

	n = parseInt(str); // пробуем преобразовать в число
	if (isNaN(n)) { // если не удалось, проверим на "true"/"false"
		switch (str.toLowerCase()) {
		case "true": return true;
		case "false": return false;
	} }
	else return (n != 0); // строка преобразована в число; ненулевое значение вернет true, нулевое - false

	// Сюда можно вставить return со значением, возвращаемым по умолчанию,
	// или поместить его в ветку default в switch.
	// В противном случае (как здесь) при неудаче парсинга
	// результатом функции будет undefined.
}

parseBool("True")    === true
parseBool("1")       === true
parseBool("115")     === true
parseBool("false")   === false
parseBool("FALSE")   === false
parseBool("0")       === false
parseBool("gh3hff4") === undefined

parseBool("true!")   === undefined // неудача: сравнение осуществляется со всей строкой, а не с ее началом; пофиксить несложно
parseBool(" false")  === undefined // неудача: пробел - тоже символ; пофиксить чуть сложнее

parseBool("1!!!")    === true // у функции parseInt свои правила
parseBool("  1")     === true // аналогично

Строго говоря, функция сработает предсказуемо только если аргумент является строкой. Но если применять ее заведомо только для строк фиксированного формата, то дополнительные проверки и вычисления не нужны.


Автор: Гость (не зарегистрирован), дата: 29 ноября, 2011 - 21:37
#permalink

сейчас кто тут есть?


Автор: Яростный Меч, дата: 20 декабря, 2011 - 17:14
#permalink

Пару слов насчет оберток для простых типов.

Обертки иногда создаются неявно, например, когда мы обращаемся к методу или свойству переменной:

var s = 'qqqqq';
alert(s.charAt(1));
s.aaa = 23;

здесь в обоих случаях создается временная обертка. charAt берется из ее прототипа и работает как ожидалось. Присвоение .aaa так же делается для временного объекта, и потому будет утеряно вместе с ним по окончании операции (alert(s.aaa) покажет undefined).

второй случай - следствие первого

String.prototype.myfunc = function() {
  alert(typeof this); // 'object'
};

s.myfunc();

третий случай - apply/call

function myfunc() {
  alert(typeof this); // снова 'object'
}

myfunc.call(s);
myfunc.apply(s);

Автор: demoniqus, дата: 29 января, 2012 - 13:19
#permalink

Автору статьи - добавьте в пункт toFixed примечание, что данный метод может также возвращать неверный результат. В примере выше со сложением 0,1 и 0,2 появляется излишек 4*10^(-17) - при округлении до двух знаков после запятой это не имеет значения в большинстве случаев (кроме округления до наименьшего целого, большего или равного исходному числу). Но в одном из моих опытов ошибка была порядка 1*10^(-2), что гораздо ощутимее (в миллион миллиардов раз). Вероятно, единственный гарантированный способ избежать подобных явлений - действительно пользоваться целочисленным исчислением - т.е. сначала привести число к целому типу, потом произвести вычисления, затем отделить необходимое количество знаков после запятой.


Автор: Quadratoff (не зарегистрирован), дата: 26 марта, 2012 - 22:18
#permalink

Например, положительная бесконечность Number.POSITIVE_INFINITY больше любого Number, и даже больше самой себя.

неправда! (Number.POSITIVE_INFINITY > Number.POSITIVE_INFINITY) === false


Автор: Гость (не зарегистрирован), дата: 31 марта, 2012 - 06:11
#permalink

плиз кто нибудь скажет как вписать своё имя в java картинку?


Автор: -Zero (не зарегистрирован), дата: 27 января, 2013 - 11:43
#permalink

Почему так?

alert(-0*0);	// 0, а не -0

Автор: Skvor, дата: 13 июня, 2013 - 03:14
#permalink

alert(-0) тоже будет 0.


Автор: Skvor, дата: 13 июня, 2013 - 03:12
#permalink

Number.POSITIVE_INFINITY больше любого Number, и даже больше самой себя

Проверьте, пожалуйста

alert(Number.POSITIVE_INFINITY < Number.POSITIVE_INFINITY);
alert(Number.POSITIVE_INFINITY > Number.POSITIVE_INFINITY);
alert(Number.POSITIVE_INFINITY == Number.POSITIVE_INFINITY);

У меня получилось false, false, true. Хотя по мне было бы логичным всегда false, ну или maybe


Автор: Mips, дата: 31 августа, 2013 - 14:52
#permalink

Для проверки типа данных не используйте instanceof, он работает ТОЛЬКО с объектами:

console.log(true instanceof Boolean);  // false
console.log(0 instanceof Number);      // false
console.log("" instanceof String);     // false
console.log([] instanceof Array);      // true
console.log({} instanceof Object);     // true

Для ПРАВИЛЬНОГО определения типа данных я использую:

function typeOf(value) {
 return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true));         // Boolean
console.log(typeOf(0));            // Number
console.log(typeOf(""));           // String
console.log(typeOf([]));           // Array
console.log(typeOf({}));           // Object
console.log(typeOf(null));         // Null
console.log(typeOf(undefined));    // Undefined
console.log(typeOf(function(){})); // Function
var sdfgsdfg;
console.log(typeOf(sdfgsdfg));     // Undefined

Яваскрипт сам меняет тип переменной в зависимости от операции:

var a; console.log(typeOf(a)+"="+a);     // Undefined=undefined
a=[];  console.log(typeOf(a)+"="+a);     // Array=
a++;   console.log(typeOf(a)+"="+a);     // Number=1
a+=""; console.log(typeOf(a)+"="+a);     // String=1
a=!a;  console.log(typeOf(a)+"="+a);     // Boolean=false
a=a/0;  console.log(typeOf(a)+"="+a);    // Number=NaN

ps: надеюсь кому-то помог


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
6 + 3 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Реклама
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum