Как правильно проверить тип переменной в JavaScript. replace() может получать возвратную функцию. Firefox читает и возвращает значение цвета в формате RGB, а не hex
В этой статье подробно рассмотрим числа, математические операторы, способы преобразования числа в строку и наоборот, а также много других важных моментов.
Функция isFiniteФункция isFinite позволяет проверить, является ли аргумент конечным числом.
В качестве ответа данная функция возвращает false , если аргумент является Infinity , -Infinity , NaN или будет быть приведён к одному из этих специальных числовых значений. В противном случае данная функция вернёт значение true .
IsFinite(73); // true isFinite(-1/0); // false isFinite(Infinity); // false isFinite(NaN); // false isFinite("Текст"); // false
Кроме глобальной функции isFinite в JavaScript имеется ещё метод Number.isFinite . Он в отличие от isFinite не осуществляет принудительное приведения аргумента к числу.
IsFinite("73"); // true Number.isFinite("73"); // false
Функция isNaNФункция isNaN предназначена для определения того, является ли аргумент числом или может ли быть преобразован к нему. Если это так, то функция isNaN возвращает false. В противном случае она возвращает true.
IsNaN(NaN); //true isNaN("25px"); //true, т.к. 20px - это не число isNaN(25.5); //false isNaN("25.5"); //false isNaN(" "); //false, т.к. пробел или неcколько пробелов преобразуется к 0 isNaN(null); //false, т.к. значение null преобразуется к 0 isNaN(true); //false, т.к. значение true преобразуется к 1 isNaN(false); //false, т.к. значение false преобразуется к 0
Если это действие нужно выполнить без приведения типа, то используйте метод Number.isNaN . Данный метод был введён в язык, начиная с ECMAScript 6.
Как явно преобразовать строку в число?Явно привести строку в число можно посредством следующих способов:
1. Использовать унарный оператор + , который необходимо поместить перед значением.
+"7.35"; // 7.35 +"текст"; // NaN
Этот способ пренебрегает пробелами в начале и конце строки, а также \n (переводом строки).
+" 7.35 "; //7.35 +"7.35 \n "; //7.35
Используя данный способ необходимо обратить внимание на то, что пустая строка или строка, состоящая из пробелов и \n , переводится в число 0. Кроме этого она также преобразует тип данных null и логические значения к числу.
Null; //0 +true; //1 +false; //0 +" "; //0
2. Функция parseInt . Данная функция предназначена для преобразования аргумента в целое число . В отличие от использования унарного оператора + , данный метод позволяет преобразовать строку в число, в которой не все символы являются цифровыми . Начинает она преобразовывать строку, начиная с первого символа. И как только она встречает символ, не являющийся цифровым, данная функция останавливает свою работу и возвращает полученное число.
ParseInt("18px"); //18 parseInt("33.3%"); //33
Данная функция может работать с разными системами счисления (двоичной, восьмеричной, десятичной, шестнадцатеричной). Указание основание системы счисления осуществляется посредством 2 аргумента.
ParseInt("18px", 10); //18 parseInt("33.3%", 10); //33 parseInt("101",2); //5 parseInt("B5",16); //181
Кроме функции parseInt в JavaScript имеется метод Number.parseInt . Данный метод ничем не отличается от функции parseInt и был введён в JavaScript со спецификацией ECMASCRIPT 2015 (6).
3. Функция parseFloat . Функция parseFloat аналогична parseInt , за исключением того что позволяет выполнить преобразование аргумента в дробное число.
ParseFloat("33.3%"); //33.3
Кроме этого функция parseFloat в отличие от parseInt не имеет 2 аргумента, и следовательно она всегда пытается рассмотреть строку как число в десятичной системе счисления.
ParseFloat("3.14"); parseFloat("314e-2"); parseFloat("0.0314E+2");
Кроме функции parseFloat в JavaScript имеется метод Number.parseFloat . Данный метод ничем не отличается от функции parseFloat и был введён в JavaScript со спецификацией ECMASCRIPT 2015 (6).
Преобразование числа в строкуПревратить число в строку можно с помощью метода toString .
(12.8).toString(); //"12.8"
Метод toString позволяет также указать основание системы счисления с учётом которой необходимо явно привести число к строке:
(255).toString(16); //"ff"
Как проверить является ли переменная числомОпределить является ли значение переменной числом можно используя один из следующих способов:
1. С использованием функций isNaN и isFinite:
// myVar - переменная if (!isNaN(parseFloat(myVar)) && isFinite(parseFloat(myVar))) { //myVar - это число или может быть приведено к нему };
В виде функции:
// функция function isNumeric(value) { return !isNaN(parseFloat(value)) && isFinite(parseFloat(value)); } // использование var myVar = "12px"; console.log(isNumeric(myVar)); //true
Этот способ позволяет определить является ли указанное значение числом или может быть приведено к нему. Данный вариант не считает числом пустую строку, строку из пробелов, значение null , Infinity , -Infinity , true и false .
2. С использованием оператора typeof и функций isFinite, isNaN:
// функция которая проверяет является ли значение числом function isNumber(value) { return typeof value === "number" && isFinite(value) && !isNaN(value); }; // использование функции isNumber isNumber(18); //true // использование функций для проверки текстовых значений isNumber(parseFloat("")); //false isNumber(parseFloat("Infinity")); //false isNumber(parseFloat("12px")); //true
Эта функция определяет имеет ли указанное значение тип Number, а также не принадлежит ли оно к одному из специальных значений Infinity, -Infinity и NaN. Эсли это так, то данная функция возвращает значение true.
3. С помощью метода ECMAScript 6 Number.isInteger(value) . Данный метод позволяет определить, является ли указанное значение целым числом.
Number.isInteger("20"); //false, т.к. данный метод не выполняет перевод строки в число Number.isInteger(20); //true, т.к. данное значение является числом
Чётные и нечётные числаПроверить является ли число чётным или нечётным можно посредством следующих функций:
// Функция для проверки числа на чётность function isEven(n) { return n % 2 == 0; } // Функция для проверки числа на нечётность function isOdd(n) { return Math.abs(n % 2) == 1; }
Но перед тем как проводить такую проверку желательно убедиться что указанное значение является числом:
Value = 20; if (Number.isInteger(value)) { if (isEven(value)) { console.log("Число " + value.toString() + " - чётное"); } }
Простые числа в JavascriptРассмотрим пример в котором выведем с помощью Javascript простые числа от 2 до 100.
// Функция, которая проверяет является ли число простым function isPrime(value) { if (isNaN(value) || !isFinite(value) || value%1 || value < 2) return false; var max=Math.floor(Math.sqrt(value)); for (var i = 2; i< = max; i++) { if (value%i==0) { return false; } } return true; } // создать массив, который будет содержать простые числа от 2 до 100 var primaryNumber = ; for (var i = 2; i
Округление числа в JavascriptОкруглить дробное число до целого значения в JavaScript можно различными способами.
1. Используя специально предназначенные для этого методы Math.floor , Math.ceil и Math.round . Метод Math.floor округляет дробное число до ближайшего целого вниз, т.е. попросту отбрасывает дробную часть. Math.ceil скругляет дробное число до ближайшего целого вверх. Math.round округляет число вверх или вниз в зависимости от значения дробной части. Если дробная часть больше или равно 0.5, то вверх, иначе скруление осуществляется вниз.
Console.log(Math.floor(7.9)); //7 console.log(Math.ceil(7.2)); //8 console.log(Math.round(7.5)); //8
2. С помощью метода toFixed(точность) . Данный метод округляет дробную часть числа до заданной точности. Результат округления возвращает в виде строки.
Console.log(7.987.toFixed(2)); //"7.99"
Если знаков после запятой для формирования указанной точности числа не хватает, то оно дополняется нулями.
Console.log(7.987.toFixed(5)); //"7.98700"
3. Посредством метода toPrecision(точность) . Данный метод представляет число с указанной точностью. При этом он может округлить не только дробную, но и целую часть числа. Полученное число данный метод может представить в зависимости от результата с фиксированной запятой или в экспоненциальной форме.
Console.log((1001).toPrecision(2)); //"1.0e+3" console.log((1001).toPrecision(5)); //"1001.0" console.log((12.4).toPrecision(1)); //"1e+1" console.log((12.4).toPrecision(2)); //"12" console.log((12.4).toPrecision(3)); //"12.4" console.log((12.4).toPrecision(5)); //"12.400"
4. Используя логические операторы НЕ или ИЛИ.
//посредством двойного логического отрицания console.log(~~7.9); //7 // посредством использования логического ИЛИ с нулём: console.log(7.9^0); //7
Целая и дробная часть числаПолучить целую часть числа можно используя метод Math.floor() и parseInt() :
Console.log(Math.floor(7.21)); // 7 console.log(parseInt(7.21)); // 7
Получить дробную часть числа можно воспользовавшимся оператором процент (%). Данный оператор возвращает остаток, который будет получен от деления первого числа на второе. В данном случае в качестве 2 числа необходимо использовать 1.
Console.log(7.21%1); // 0.20999999999999996 // с точностью до 2 знаков после запятой console.log((7.21%1).toFixed(2)); // "0.21"
Кроме этого дробную часть можно получить также с помощью вычислений:
Var number = 7.21; var fractionNumber = number - Math.floor(Math.abs(number)); console.log(fractionNumber); // 0.20999999999999996
Делится ли число нацелоОпределить делится ли число нацело можно используя оператор процента:
Var number = 9; // если остаток от деления числа number на 3 равен 0, то да, иначе нет if (number%3==0) { console.log ("Число " + number + " делится на 3"); } else { console.log ("Число " + number + " не делится на 3"); }
Форматирование чиселВ JavaScript отформатировать вывод числа в соответствии с региональными стандартами (языковыми настройками операционной системы) позволяет метод toLocaleString() .
Например, выполним форматирование числа в соответствии с региональными стандартами, которые установлены в системе по умолчанию:
Var number = 345.46; console.log(number.toLocaleString()); //"345,46"
Например, выполним форматирование числа в соответствии с региональными стандартами России (ru):
Console.log((108.1).toLocaleString("ru-RU")); //"108,1"
Данный метод можно также использовать для форматирования числа в виде валюты:
Console.log((2540.125).toLocaleString("ru-RU",{style:"currency", currency:"RUB"})); //"2 540,13 ₽" console.log((89.3).toLocaleString("ru-RU",{style:"currency", currency:"USD"})); //"89,30 $" console.log((2301.99).toLocaleString("ru-RU",{style:"currency", currency:"EUR"})); //"2 301,99 €"
Представление числа в виде процентов:
Console.log((0.45).toLocaleString("ru-RU",{style:"percent"})); //"45 %"
Разбить число на разряды (свойство useGrouping):
Console.log((125452.32).toLocaleString("ru-RU",{useGrouping:true})); //"125 452,32"
Вывести с число с определённым количеством цифр (2) после запятой:
Console.log((1240.4564).toLocaleString("ru-RU",{minimumFractionDigits:2, maximumFractionDigits:2})); //"1 240,46"
Сравнение чиселДля сравнения чисел в JavaScript используются следующие операторы: == (равно), != (не равно), > (больше), < (меньше), >= (больше или равно), 3); //false console.log(5>=3); //true
При сравнении чисел с дробной частью необходимо учитывать погрешности, которые могут возникать во время этих вычислений.
Например, в JavaScript сумма чисел (0.2 + 0.4) не равна 0.6:
Console.log((0.2+0.4)==0.6); //false
Погрешности происходят потому что все вычисления компьютер или другое электронное устройство производит в 2 системе счисления. Т.е. перед тем как выполнить какие-то действия компьютер сначала должен преобразовать представленные в выражении числа в 2 систему счисления. Но, не любое дробное десятичное число можно представить в 2 системе счисления точно.
Например, число 0.25 10 в двоичную систему преобразуется точно.
0.125 × 2 = 0.25 | 0 0.25 × 2 = 0.5 | 0 0.5 × 2 = 1 | 1 0.125 10 = 0.001 2
Например, число 0.2 10 можно преобразовать в 2 систему только с определённой точностью:
0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 ... 0.2 10 = 0.001100110011... 2
В результате эти погрешности скажутся при вычисления суммы двух чисел и результатах сравнения. Т.е. получится что на самом деле JavaScript будет видет эту запись следующим образом:
0.6000000000000001==0.6
При вычислениях или отображении чисел с дробной частью необходимо всегда указывать точность, с которой это необходимо делать.
Например, сравнить числа до 2 знаков после запятой используя методы toFixed() и toPrecision() :
//метод toFixed() console.log((0.2+0.4).toFixed(2)==(0.6).toFixed(2)); //true //метод toPrecision() console.log((0.2+0.4).toPrecision(2)==(0.6).toPrecision(2)); //true
Основные математические операцииВ JavaScript существуют следующие математические операторы: + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления), ++ (увелить значение на 1), -- (уменьшить значение на 1).
6+3 //9 6-3 //3 6*3 //18 6/3 //2 6%3 //0, т.е. 6:3=2 => 6-3*2 => ост(0) 5%2 //1, т.е. 5:2=2(.5) => 5-2*2 => ост(1) 7.3%2 //1.3, т.е. 7.3:2=3(.65) => 7.3-2*3 => ост(1.3) //знак результата операции % равен знаку первого значения -9%2.5 //-1.5, т.е. 9:2.5=3(.6) => 9-2.5*3 => ост(1.5) -9%-2.5 //-1.5, т.е. 9:2.5=3(.6) => 9-2.5*3 => ост(1.5) -2%5 //-2, т.е. 2:5=0(.4) => 2-5*0 => ост(2) x = 3; console.log(x++); //выводит 3, у уже потом устанавливает 4 console.log(x); //4 x = 3; console.log(++x); //устанавливает 4 и выводит x = 5; console.log(x--); //выводит 5, у уже потом устанавливает 4 console.log(x); //4 x = 5; console.log(--x); //устанавливает 4 и выводит Кроме этого в JavaScript есть комбинированные операторы: x+=y (x=x+y), x-=y (x=x-y), x*=y (x=x*y), x/=y (x=x/y), x%=y (x=x%y). x = 3; y = 6; x+=y; console.log(x); //9 x = 3; y = 6; x-=y; console.log(x); //-3 x = 3; y = 6; x*=y; console.log(x); //18 x = 3; y = 6; x/=y; console.log(x); //0.5 x = 3; y = 6; x%=y; console.log(x); //3
Существует несколько JavaScript-хаков, которыми постоянно пользуются опытные программисты. Они не совсем очевидны, особенно для новичков. Эти хаки используют возможности языка, имеющие некоторые побочные эффекты. В этой статье я объясню, как работают 5 таких распространённых хаков.
Использование оператора!! для конвертации в логическое значение Всё в JavaScript может быть интерпретировано как истинное или ложное . Это означает, что если вы поместите объект в условный оператор if , то он выполнит либо true -ветку кода (когда объект имеет значение true), либо выполнит false -ветку (соответственно, когда объект имеет значение false).0, false, "", null, undefined, NaN - это ложные значения. Все остальные значения возвращают true . Иногда вам может потребоваться конвертировать переменную в логическое значение. Это можно сделать с помощью оператора!! :
Var something = "variable"; !!something // returns true
С другой стороны, вместо if (x == "test") можно просто написать if (x) . Если же x будет пустой переменной, то просто выполнится код из блока else .
Конвертация строки в число с помощью оператора + В JavaScript + — это унарный оператор, который возвращает числовое представление операнда или NaN , если операнд не имеет такового. Например, с помощью этого оператора можно проверить, является ли переменная x числом (такой код можно увидеть в библиотеке underscore): x === +x .Такой способ не очевиден. Скорее всего, вы бы применили методы parseFloat и parseInt .
Определение значения по умолчанию с оператором || В JavaScript || является примером выполнения короткого замыкания . Этот оператор сперва анализирует выражение слева от него, и, если оно ложно, анализирует выражение справа. В любом случае, он возвращает первое истинное выражение. Рассмотрим следующий пример:Function setAge(age) { this.age = age || 10 } setAge();
В этом примере мы вызываем функцию setAge() без аргументов, таким образом age || 10 вернет 10 (!!age == false). Такой способ весьма хорош для того, чтобы задавать значения переменных по умолчанию. На самом деле, такой подход эквивалентен следующему примеру:
Var x; if (age) { this.age = age; } else { this.age = 10; }
Первый пример с оператором || более лаконичен, поэтому именно такой способ используется во всем мире.
Лично я часто использую этот способ. Мне нравится его лаконичность и простота. Однако стоит заметить, что с таким способом вам не удастся задать переменной значение 0, так как 0 является ложным выражением. Поэтому я советую при необходимости использовать такой способ:
This.age = (typeof age !== "undefined") ? age: 10;
Использование void 0 вместо undefined Ключевое слово void принимает один аргумент и всегда возвращает undefined . Почему просто не использовать undefined ? Потому что в некоторых браузерах undefined — это просто переменная, которая может быть переопределена. Поэтому void 0 даёт нам больше уверенности в том, что ничего не будет случайно сломано. Хотя вы можете найти этот хак в исходниках многих библиотек, я бы не рекомендовал использовать его регулярно, так как все ES5-совместимые браузеры не позволяют перезаписывать значение undefined .Инкапсуляция с помощью паттерна (function() {...})() В ES5 есть только 2 типа областей видимости: глобальная область видимости и область видимости функции. Всё, что вы пишите, принадлежит к глобальной области, которая доступна из любого места кода. Она включает в себя объявление переменных и функций. Однако, что если вы захотите инкапсулировать большинство кода, а в глобальной области видимости оставить только интерфейс? Тогда вам следует использовать анонимную функцию. Рассмотрим следующий пример:(function() { function div(a, b) { return a / b; } function divBy5(x) { return div(x, 5); } window.divBy5 = divBy5; })() div // => undefined divBy5(10); // => 2
Из всех перечисленных в статье хаков этот хак является самым безвредным; вы можете и должны использовать его в своих проектах, чтобы предотвратить взаимодействие внутренней логики с глобальной областью видимости.
В заключение я хотел бы напомнить вам, что любой написанный вами код должен быть прост и понятен для других программистов. И любые стандартные конструкции, предоставляемые языком, следует использовать в первую очередь.
Некоторые из хаков, рассмотренных в статье, могут быть решены элегантнее с помощью ES6 (следующая версия JavaScript). Например, в ES6 вместо age = age || 10 можно написать следующее:
Function(age = 10) { // ... }
Другой пример — паттерн (function() {...})() , который вы уже вряд ли станете использовать после того, как
JavaScript. Причудливый и все-таки прекрасный язык программирования. Если бы Пабло Пикассо был программистом, то он наверняка бы разработал именно JavaScript. Null является объектом, пустой массив эквивалентен false , а функции перебрасываются словно теннисные мячи.
Типы данных и определения 1. null - это объектНачнем с широко известной странности JavaScript. null является объектом. Сомневаетесь? Ведь данное утверждение противоречит самой сути null . Вот доказательства:
Alert(typeof null); //Выдаст сообщение "object"
Несмотря на очевидный факт, null не является реализацией никакого базового объекта. (Если вы не знали, значения в JavaScript являются реализациями базового объекта. Так, каждое число является реализацией объекта Number , каждый объект является реализацией объекта Object .) Такое положение возвращает нас обратно к практическому смыслу, потому что если null является отсутствием значения, то он не может быть реализацией какого-либо объекта. Следовательно следующее выражение возвращает false:
Alert(null instanceof Object); //Выдаст сообщение "false"
2. NaN - это числоСчитаете факт представления null объектом странным? Попробуйте проверить NaN ! Он оказывается числом! Кроме того, NaN не равен самому себе!
Alert(typeof NaN); //Выдаст сообщение "Number" alert(NaN === NaN); //Выдаст сообщение "false"
В действительности NaN не равен ничему. Единственный способ проверить значение NaN - функция isNaN() .
3. Массив без ключей == falseДругая причуда JavaScript:
Alert(new Array() == false); //Выдаст сообщение "true"
Чтобы понять, что происходит, нужно понимать концепцию истина и ложь . В данном случае имеется некий вид отношений истина/ложь, которая может привести в восторг философа или специалиста по логике.
Существует множество описаний концепции истины и лжи, но самое простое объяснение таково: в JavaScript каждое нелогическое значение имеет встроенный логический флаг , который используется тогда, когда значение должно рассматриваться как логическое, например, при сравнении с другим логическим выражением.
Чтобы произвести сравнение значений разных типов JavaScript сначала приводит их к общему типу данных. False , 0 , null , undefined , пустая строка и NaN становятся false —?только для заданного выражения сравнения. Например:
Var someVar = 0; alert(someVar == false); //Выдаст сообщение "true"
Здесь имеется попытка сравнить число 0 с логическим значением false . Так как типы данных несопоставимы, JavaScript незаметно приводит их к единому логическому эквиваленту , и в нашем случае 0 представляется как false.
В выше приведенном списке не было пустого массива. Пустой массив - любопытная штука: в действительности он рассматривается как true , но при сравнении с логическим значением он ведет себя как false . Вот так!
Var someVar = ; //Пустой массив alert(someVar == false); //Выдаст сообщение "true" if (someVar) alert("hello"); //Выполняется alert, поэтому someVar рассматривается как true
Чтобы избежать приведения типов нужно использовать оператор сравнения значений и типов === (в отличие от == , который сравнивает только значения). Например:
Var someVar = 0; alert(someVar == false); //Выдаст сообщение "true" alert(someVar === false); //Выдаст сообщение "false", 0 - число, а не логическая переменная
Регулярные выражения 4. replace() может получать возвратную функциюЭто один из самых скрытых секретов JavaScript (который появился начиная с версии 1.3). Обычно вызов функции replace() выглядит примерно так:
Alert("10 13 21 48 52".replace(/d+/g, "*")); //заменяем все числа на *
Простая замена. Но что если нужно более сложно контролировать когда и как будет производиться замена? Например, нужно заменять числа только до 30. Такая задача не может быть решена только регулярным выражением (оно может сделать все, что угодно со строкой, но не с математикой выражения). Нужно использовать возвратную функцию для вычисления соответствия.
Alert("10 13 21 48 52".replace(/d+/g, function(match) { return parseInt(match) < 30 ? "*" : match; }));
Для каждой проверки JavaScript вызывает функцию, передавая ей аргументы для проверки. А затем мы возвращаем либо звездочку, либо само число.
5. Регулярные выражения: больше, чем выделение подстроки и заменаОбычно JavaScript программисты в своей практике используют только методы match и replace для регулярных выражений. Но кроме них в JavaScript есть и другие инструменты.
Практический интерес представляет метод test() , который действует подобно match , но не возвращает значение: он просто подтверждает соответствие шаблону. То есть он легче для вычислений.
Alert(/w{3,}/.test("Hello")); //Выдаст сообщение "true"
Выше приведенный код выполняет проверку на соответствие шаблону, состоящему из трех и более буквенных и числовых символов. Так как строка Hello соответствует требованию, то мы получаем true . Но мы не получаем выделение из строки, а просто результат проверки.
Также обратите внимание на то, что с помощью объекта RegExp вы можете создавать динамические регулярные выражения. В основном регулярные выражения составляются с использованием коротких форм (то есть строк, заключенных в прямые слеши) и в них нельзя использовать переменные . Но RegExp() позволяет обойти ограничение.
Function findWord(word, string) { var instancesOfWord = string.match(new RegExp("\b"+word+"\b", "ig")); alert(instancesOfWord); } findWord("car", "Carl went to buy a car but had forgotten his credit card.");
Здесь мы создаем динамический шаблон на основе значения аргумента word . Функция возвращает количество совпадений полного слова word (то есть не являющегося частью других слов) в строке. В нашем примере car встречается один раз, а слова Carl и card игнорируются.
Так как RegExp определяется строкой, а не через синтаксис с обратными слешами, то мы можем использовать переменные для построения шаблона. Но специальные символы в данном случае требуют к себе повышенного внимания, как символы границы слова в нашем примере.
Функции и область видимости 6. Вы можете обманывать область видимостиОбласть видимости, в которой выполняется код, определяет доступность переменных. Свободный код JavaScript (то есть код, который выполняется вне какой-либо функции) оперирует глобальной областью видимости объекта window , где имеет доступ ко всему. А локальные переменные, объявленные внутри функции, доступны только внутри данной функции, но не вне ее.
Var animal = "dog"; function getAnimal(adjective) { alert(adjective+" "+this.animal); } getAnimal("lovely"); //Выдаст сообщение "lovely dog";
В данном примере наша переменная и функция объявлены в глобальной области видимости (то есть в window). Так как this всегда указывает на текущую область видимости, то здесь он указывает на window . Следовательно функция ищет window.animal . Нормальная ситуация. Но мы можем заставить нашу функцию считать, что она выполняется в другой области видимости, которая отличается от ее нормального состояния. Для этого используется встроенный метод call() для вызова функции:
Var animal = "dog"; function getAnimal(adjective) { alert(adjective+" "+this.animal); }; var myObj = {animal: "camel"}; getAnimal.call(myObj, "lovely"); //Выдаст сообщение "lovely camel"
Здесь функция выполняется не в window, а в myObj , что определяется первым аргументом при вызове метода call. По существу метод call() имитирует ситуацию, что наша функция является методом myObj . Обратите внимание, что все переданные аргументы после первого в метод call() передаются в нашу функцию - здесь lovely становится значением аргумента adjective .
Опытные разработчики JavaScript наверняка скажут, что годы работают без использования данного метода, потому что хорошо продуманный код не нуждается в шаманстве с бубнами. Но, тем не менее, описанная ситуация представляет определенный интерес.
Также есть метод apply(), который действует аналогично call() , за исключением того, что аргументы должны быть указаны в массиве. Выше приведенный пример с использованием apply() будет выглядеть так:
GetAnimal.apply(myObj, ["lovely"]); //аргументы функции отправляются как массив
7. Функция может вызывать сама себяСложно отрицать следующий факт:
(function() { alert("hello"); })(); //Выдаст сообщение "hello"
Синтаксис примера достаточно прост: мы объявляем функцию и немедленно вызываем ее, как другую с помощью синтаксиса () . Может возникнуть вопрос "А зачем так делать?". Обычно, функция содержит код, который планируется использовать позже и в другом месте, иначе не нужно размещать его в функции.
Хорошим примером использования самовызывающихся функций (они иногда обозначаются аббревиатурой SEF) является привязка текущего значения переменной для использования внутри отложенного кода, такого как возвратные функции для событий, таймаутов и интервалов. Есть проблема:
Var someVar = "hello"; setTimeout(function() { alert(someVar); }, 1000); var someVar = "goodbye";
Новички бывают удивлены тем, что Newbies функция alert в timeout выдает goodbye, а не hello . Ответ достаточно прост возвратная функция timeout не вычисляет значения someVar до момента своего выполнения, поэтому в ней оказывается значение goodbye .
Самовызываюшиеся функции обеспечивают решение данной проблемы. Вместо определения возвратной функции имплицитно, как в выше приведенном примере, мы возвращаем ее из самовызывающейся функции, в которую передаем текущее значение someVar в качестве аргумента. то есть мы передаем и изолируем текущее значение переменной someVar , защищая его от последующих модификаций someVar . Очень похоже на фотографию, которая хранит образ во времени.
Var someVar = "hello"; setTimeout((function(someVar) { return function() { alert(someVar); } })(someVar), 1000); var someVar = "goodbye";
В данном примере код выдаст сообщение hello , так как используется изолированное значение someVar (то есть аргумент функции, а не внешняя переменная).
Браузеры 8. Firefox читает и возвращает значение цвета в формате RGB , а не hexНепонятно, почему Mozilla так делает. Определенно, из JavaScript удобнее работать с форматом hex , а не RGB. Например:
Текст var ie = navigator.appVersion.indexOf("MSIE") != -1; var p = document.getElementById("somePara"); alert(ie ? p.currentStyle.color: getComputedStyle(p, null).color);
Большинство браузеров выведут ff9900 , а Firefox - rgb(255, 153, 0) . Нужно использовать функцию JavaScript для конвертации RGB в hex .
Обратите внимание, что в данном случае мы говорим о вычисляемом цвете, а не о том, как он определяется для элемента. Также IE имеет отличный метод для вычисления стилей.
Метод jQuery css() возвращает значение, определяемое в стиле для элемента. Поэтому, для действительного значения нужно использовать getComputedStyle и currentStyle .
Разное 9. 0.1 + 0.2 !== 0.3Данная причуда касается не только JavaScript, а всего компьютерного окружения и проявляется во многих языках. Вычисленное значение равно 0.30000000000000004.
Это действие точности вычислений. Когда JavaScript производит вычисления, он конвертирует значения в бинарные эквиваленты. И здесь появляется проблема, так как 0.1 не может быть совершенно точно представлено в бинарном эквиваленте, который используется для бинарных операций с плавающей точкой.
Для того чтобы преодолеть данный казус есть два метода (выбор за вами):
Например, вместо такого кода:
Var num1 = 0.1, num2 = 0.2, shouldEqual = 0.3; alert(num1 + num2 == shouldEqual); //Выдаст сообщение "false"
Можно построить выражение так:
Alert(num1 + num2 > shouldEqual - 0.001 && num1 + num2 < shouldEqual + 0.001); //Выдаст сообщение "true"
В данном примере результат сложения 0.1 + 0.2 оценивается как попадание в диапазон чисел около 0.3 с точностью 0.001. Для точных вычислений такой метод явно подходит плохо.
10. Undefined может быть DefinedЗвучит, конечно, странно, но undefined не является зарезервированным словом в JavaScript, хотя и имеет специальное значение для выявления неопределенных переменных:
Var someVar; alert(someVar == undefined); //Выдаст сообщение "true"
На первый взгляд все отлично. Но:
Undefined = "Я имею значение!"; var someVar; alert(someVar == undefined); //Выдаст сообщение "false"!