Полезные заметки JavaScript

Ознакомимся с несколькими полезных приемами программирования в JavaScript, вместо которых мы часто пишем намного более громоздкие конструкции.

Конвертирование переменных

Как ни странно, но иногда для конвертирования переменных одного типа в другой используют конструкторы объектов типа Array() или Number(). На самом деле правильнее и лучше (с точки зрения производительности) использовать примитивные типы данных:

var myVar   = "3.14159",  
str = ""+ myVar,// в стринг (string)
int = ~~myVar, // в интеджер (integer)
float = 1*myVar, // во флоат (float)
bool = !!myVar, // в булен - все непустые строки и числа кроме 0 будут true
array = [myVar]; // в массив

Конвертирование в даты (new Date(myVar)) и регулярные выражения (new RegExp(myVar)) нужно делать с использованием конструкторов. Всегда используйте структуру /регулярное_выражение/флаги при создании регулярных выражений.

Округление числа до нужной точности после запятой:

1.234.toFixed(2)

В результате получим число 1.23

Замена всех вхождений подстроки в строку

Часто случается, что нужно заменить все вхождения какой-то строки в другую строку. Вместо громоздких конструкций лучше всего делать так:

var str = "foobarfoobar";
str.replace(/foo/g,"xxx");
// в итоге получиться str = "xxxbarxxxbar";

Передача аргументов функции

В JavaScript действуют следующие правила передачи аргументов функции:

Аргументы примитивных типов - передаются в функцию по значению. Иными словами, формальным аргументам присваиваются значения фактических аргументов на момент вызова и, если даже операторы в теле функции изменят значение какого-либо аргумента, то это изменение не коснется переменной, чье значение передавалось в качестве аргумента. Например:

function setBrowser(browser) {
   browser = "Internet Explorer";
}
var myBrowser = "Netscape Navigator";
setBrowser(myBrowser);  // объект myBrowser передается функции
alert(myBrowser); // выводит "Netscape Navigator"

Объекты (и встроенные, и определенные пользователем) передаются по ссылке. Это означает, что все изменения свойств объекта в теле функции производятся непосредственно в самом объекте, а не в его локальной копии и, следовательно, сохраняются после возврата из функции. Например:

function setBrowser(browser) {
   browser.name = "Internet Explorer";
   browser.version = "5.5";
}
var myBrowser = {
  name:"Netscape Navigator",
  version:"4.7"
};
setBrowser(myBrowser);  // объект myBrowser передается функции
alert(myBrowser.name); // выводит "Internet Explorer"

Необязательные аргументы функции

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

function doSomething() {  
// Оставляем аргументы, если ничего не передано
if (!arguments[0]) {
return false;
}

var oArgs = arguments[0]
arg0 = oArgs.arg0 || "",
arg1 = oArgs.arg1 || "",
arg2 = oArgs.arg2 || 0,
arg3 = oArgs.arg3 || [],
arg4 = oArgs.arg4 || false;
}

doSomething({
arg1 : "foo",
arg2 : 5,
arg4 : false
});

Замыкания

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

var mydata = [
    {
        name : "foo"
    },
    {
        name : "bar"
    }
];

Пробежимся по объекту и заполним массив новыми объектами (взяв данные у объекта выше):

var result = [];
for (var i = 0; mydata.length > i; i++) {
    var my = mydata[i];// берем объект из массива
    var info = {// создаем объект с функцией, которая будет возвращать имя объекта
        showName: function () {
            return my.name;
        }
    };
    result.push(info);
}
console.log(result[0].showName());// неправильно bar (лично я ожидал foo)
console.log(result[1].showName());// правильно bar

Ошибка просиходит потому, что мы забыли заинитить переменную в функции showName, поэтому согласно поведению LexicalEnvironment, значение будет искаться в вышестоящем [[Scope]].

Так давайте передадим аргумент в функцию, а не будем использовать значение из [[Scope]].

...
        showName: function (my) {
            return my.name;
        }(my)
...

проверим результат:

console.log(result[0].showName);// правильно foo
console.log(result[1].showName);// правильно bar

* ОБРАТИТЕ ВНИМАНИЕ: теперь поле showName формально перестало быть функцией (пока не разобрался почему), но на практике, вы можете поместить в эту все еще функцию любой вызов, и он выполнится.

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

...
    var closuredData = function(my){
        var info = {// создаем объект с функцией, которая будет возвращать имя объекта
            showName: function () {
                return my.name;
            }
        };
        result.push(info);
    }(my);
...

и теперь, наш ключ, снова является классической функцией:

console.log(result[0].showName());// правильно foo
console.log(result[1].showName());// правильно bar

Всем удачи.

Источники: 1 - 2

 

Передача аргументов функции

Когда у какой-то функции есть как обязательные, так и необязательные аргументы, то ее вызов может выглядеть как-то так:

function doSomething(arg0, arg1, arg2, arg3, arg4) {  
...
}

doSomething('', 'foo', 5, [], false);

Хотя на самом деле всегда проще передавать только один объект вместо нескольких обычных аргументов:

function doSomething() {  
// Оставляем аргументы, если ничего не передано
if (!arguments[0]) {
return false;
}

var oArgs = arguments[0]
arg0 = oArgs.arg0 || "",
arg1 = oArgs.arg1 || "",
arg2 = oArgs.arg2 || 0,
arg3 = oArgs.arg3 || [],
arg4 = oArgs.arg4 || false;
}

doSomething({
arg1 : "foo",
arg2 : 5,
arg4 : false
});
Оцени публикацию:
  • 7,31
Оценили человек: 7

Похожие статьи:

Справочники и учебники:


Предложения и пожелания:
Ваше имя:
Ваш E-mail:
Введите изображенные цифры:
Captcha
Главная
X

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2017 YaPro.Ru

Главная » Веб-мастеру » JavaScript »