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

Форум

Учебник Node.JS скринкаст Стандарт языка

Справочник

Discord чат

 
Статьи Тест знаний Аналоги функций PHP

Курсы javascript

 

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, а данных нет. Понимайте как хотите.

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

Number

Неточные вычисления.

Все числа хранятся в формате 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() и т.д

String

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

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

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

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

Boolean

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

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

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

Boolean(a) == !!a

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

#permalink

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




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

#permalink

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

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

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


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

#permalink

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

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

Спасибо


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

#permalink

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


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

#permalink

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

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


Автор: Гость (не зарегистрирован), дата: 13 июня, 2009 - 21:21

#permalink
alert(0.1+0.2);

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





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

#permalink

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

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


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

#permalink

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


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

#permalink

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

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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


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

#permalink

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

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

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


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

#permalink

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


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

#permalink

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


Автор: Яростный Меч, дата: 20 декабря, 2011 - 16: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 - 12:19

#permalink

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


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

#permalink

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

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


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

#permalink

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


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

#permalink

Почему так?

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

Автор: Skvor, дата: 13 июня, 2013 - 02: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 - 13: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: надеюсь кому-то помог


Автор: wan-derer.ru (не зарегистрирован), дата: 21 января, 2017 - 15:23

#permalink

Подскажите, есть ли встроенный способ замены регистра строки? Т.е. на входе "МедвеД", на выходе "медвед" или "МЕДВЕД".


Автор: Гость (не зарегистрирован), дата: 24 марта, 2022 - 18:13

#permalink

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


Автор: Гость (не зарегистрирован), дата: 19 июля, 2023 - 06:10

#permalink

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

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


 
Текущий раздел
Поиск по сайту
Содержание

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

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