Статьи

AZ JavaScript


Вот список A — Z некоторых идиом и шаблонов Javascript.
Идея состоит в том, чтобы передать простым языком некоторые особенности реального языка Javascript (а не то, как он может взаимодействовать с DOM). Наслаждайтесь …

Литералы массива Литерал

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

var months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
                     'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
console.log(months[0]); // outputs jan
console.log(months.length) // outputs 12

Массивы в JavaScript имеют широкий выбор методов, включая push () и pop (). Предположим, что мир был захвачен диктатором, который хотел избавиться от последнего месяца года? Диктатор просто сделает …

months.pop();

И, конечно же, диктатор со временем захочет добавить месяц после себя, когда всем придется ему поклоняться:

months.push("me");

Обратные вызовы

Поскольку функции являются объектами, они могут передаваться в качестве аргументов другим функциям.

function peakOil(callback) {
    //... code
    callback();  // the parentheses mean the function is executed!
}

function changeCivilisationCallback(){
   //...
}

// Now pass the changeCivilisationCallback to peakOil.
// Note: no changeCivilisationCallback parentheses because it is not
// executed at this point.
// It will be excuted later inside peak oil.
peakOil(changeCivilisationCallback); 

В приведенном выше
примере функция обратного вызова chanceCivilisationCallback вызывается
peakOil . Можно добавить логику, чтобы проверить, достаточно ли возврата энергии от солнечных батарей и ветряных электростанций, и в этом случае может быть добавлен другой обратный вызов, отличный от
changeCivilisationCallback .

Объект конфигурации 

Вместо того, чтобы передавать кучу связанных свойств …

function addCar(colour, wheelsize, regplate) {...}

Используйте объект конфигурации

function addCar(carConf) {...}

var myCarConf = {
    colour: "blue",
    wheelsize: "32",
    regplate: "00D98788"
};
addCar(myCarConf);

Использование объекта конфигурации облегчает написание чистых API, которые не должны принимать огромный длинный список параметров. Они также означают, что у вас меньше шансов получить глупые ошибки, если параметры в неправильном порядке.

Замыкания

Существует три способа создания объектов в Javascript: использование литералов, использование функции-конструктора и замыкание. Что замыкания предлагают, что два других подхода не делают, это
инкапсуляция . Замыкания позволяют скрывать функции и переменные.

var counter = function(count) {
    console.log(">> setting count to " + this.count);
    return {
        getCount: function(){
           return ++count;
        }
    }
}

mycounter = counter(0);
console.log(mycounter.getCount());  // outputs 1
console.log(mycounter.getCount());  // outputs 2
console.log(mycounter.getCount());  // outputs 3
console.log(mycounter.getCount());  // outputs 4

// Same again with offset this time.
mycounterWithOffset = counter(10);
console.log(mycounterWithOffset .getCount());  // outputs 11
console.log(mycounterWithOffset .getCount());  // outputs 12
console.log(mycounterWithOffset .getCount());  // outputs 13
console.log(mycounterWithOffset .getCount());  // outputs 14

Примечание. Замыкание — это литерал объекта, возвращаемый из анномальной функции. Он «закрывается» над переменной count. Никто не может получить к нему доступ, кроме закрытия. Это заключено в капсулу. Закрытие также имеет чувство состояния. Также обратите внимание, как он поддерживает значение счетчика.

Функции конструктора (встроенные)

В Javascript нет классов, но есть функции-конструкторы, которые используют
новый синтаксис ключевого слова, аналогичный созданию объектов на основе классов в Java или других языках. Javascript имеет несколько встроенных функций конструктора. К ним относятся Object (), Date (), String () и т. Д.

var person = new Object();  // person variable is an Object
person.name = "alex";  // properties can then be dynamically added

Функции конструктора (пользовательские)

Когда функция вызывается с ключевым словом
new , она называется функцией конструктора. В
новых средствах , что новый объект будет иметь скрытую ссылку на значение функции в
прототипе элемента и
этого ключевое слово будет привязаны к новому объекту.

function MyConstrutorFunction() {
    this.goodblog = "dublintech.blogspot.com";
}

var newObject = new MyConstrutorFunction();
console.log(typeof newObject);    // "object"
console.log(newObject.goodblog);  // "dublintech.blogspot.com"

var noNewObject = MyConstrutorFunction();
console.log(typeof noNewObject);  // "undefined"
console.log(window.tastes);       // "yummy"

Соглашение состоит в том, что функции конструктора должны начинаться с заглавной буквы. Примечание: если
ключевое слово
new не используется, то
переменная
this внутри функции будет ссылаться на глобальный объект. Ты чувствуешь запах потенциального беспорядка? Следовательно, почему используется заглавная буква для функций конструктора. Прописная буква означает: «Я — функция конструктора, используйте
новое ключевое слово».

Curry 

Curry — это процесс уменьшения количества аргументов, передаваемых функции, путем установки некоторых аргументов в предварительно заданные значения. Рассмотрим эту функцию.

function outputNumbers(begin, end) {
    var i;
    for (i = begin; i <= end; i++) {
        print(i);
    }
}
outputNumbers(0, 5);  // outputs 0, 1, 2, 3, 4, 5
outputNumbers(1, 5);  // outputs 1, 2, 3, 4, 5

Предположим, мы хотим подобную функцию с фиксированным значением начала. Допустим, значение «begin» всегда было 1. Мы могли бы сделать:

function outputNumbersFixedStart(start) {
    return function(end) {
        return outputNumbers(start, end);
    }
}

А затем определить переменную, которая будет этой новой функцией …

var outputFromOne = outputNumbersFixedStart(1);
outputFromOne(3);  1, 2, 3
outputFromOne(5);  1, 2, 3, 4, 5

Оператор

удаления Оператор удаления можно использовать для удаления свойств из объектов и массивов.

var person = {name: 'Alex', age: 56};
// damn I don't want them to know my age remove it
delete person.age;
console.log("name" in person);  // outputs true because it is still there
console.log("age" in person);   // outputs false


var colours = ['red', 'green', 'blue']
// is red really in the array?
console.log(colours.indexOf('red') > -1);  // outputs true.
// remove red, it's going out of fashion!
delete colours[colours.indexOf('red')];
console.log(colours.indexOf('red') > -1);  // outputs false
console.log(colours.length) // length is still three, remember it's javascript!

Вы не можете удалить глобальные переменные или атрибуты прототипа.

console.log(delete Object.prototype)  // can't be deleted, outputs false
function MyFunction() {
    // ...
}
console.log(delete MyFunction.prototype) // can't be deleted, outputs false

var myglobalVar = 1;
console.log(delete this.myglobalVar)   // can't be delete, outputs false

Динамические аргументы

Аргументы для функции не обязательно указывать в определении функции

function myFunction(){
   // ... Note myfunction has no arguments in signature
   for(var i=0; i < arguments.length; i++){
       alert(arguments[i].value);
   }
}

myFunction("tony", "Magoo");  // any argument can be specified

Параметр arguments является массивом, доступным для функций, и предоставляет доступ ко всем аргументам, которые были указаны в вызове.

итерации

for-in Циклы for-in (также называемые перечислениями) должны использоваться для итерации объектов, не являющихся массивами.

var counties = {
    dublin: "good",
    kildare: "not bad",
    cork: "avoid"
}

for (var i in counties) {
    if (counties.hasOwnProperty(i)) { // filter out prototype properties
        console.log(i, ":", counties[i]);
    }
}

Объявление функции

В объявлении функции функция стоит сама по себе и ей не нужно ничего назначать.

function multiple(a, b) {
    return a * b; 
} // Note, no semi colon is needed 

Выражения

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

multiply = function multiplyFunction(a, b) {
    return a * b;
}; // Note the semi colan must be placed after the function definition

console.log(multiply(5, 10)); // outputs 50

В приведенном выше примере функция названа. Он также может быть анонимным, в этом случае свойство name будет пустой строкой.

multiply = function (a, b) {
   return a * b;
} // Note the semi colan must be placed after the function definition

console.log(multiply(5, 10)); // outputs 50

Функциональное наследование

Функциональное наследование — это механизм наследования, который обеспечивает инкапсуляцию с помощью замыканий. Прежде чем пытаться понять синтаксис, сначала возьмем пример. Предположим, мы хотим представлять планеты в Солнечной системе. Мы решили иметь
базовый объект
планеты, а затем несколько дочерних объектов планеты, которые наследуются от базового объекта. Вот базовый объект планеты:

var planet = function(spec) {
    var that = {};
    that.getName = function() {
        return spec.radius;
    };
    that.getNumberOfMoons()= function() {
        return spec.numberOfMoons;
    };
    return that;
}

Теперь о некоторых планетах. Давайте начнем с Земли и Юпитера, и, чтобы развлечься, давайте добавим функцию для Земли, чтобы люди уходили, и функцию для Юпитера для людей, прибывающих.
Сара Пэйлин вступила во владение, и все стало довольно плохо !!!

var earth = function(spec) {
    var that = planet{spec};   // No need for new keyword!
    that.peopleLeave = function() {
        // ... people leave
    }
    return that;
}

var jupiter = function(spec) {
    var that = planet(spec); 
    that.peopleArrive = function() {
       // .. people arrive
    }
    return that;
}

Теперь приведите Землю и Юпитер в движение …

var myEarth = earth({name:"earth",numberofmoons:1});
var myjupiter=jupiter({name:"jupiter",numberofmoons:66});

Три ключевых момента здесь:

  1. Есть повторное использование кода.
  2. Существует инкапсуляция. Свойства name и numberOfMoons инкапсулированы.
  3. Дочерние объекты могут добавлять свои специфические функции.

Теперь объяснение синтаксиса:

  1. Планета базового объекта принимает некоторые данные в объекте спецификации .
  2. Базовый объект планеты создает замыкания, называемые тем, что возвращается. , Что объект имеет доступ ко всему , в спецификации объекта. Но больше ничего не делает. Это обеспечивает уровень инкапсуляции.
  3. Дочерние объекты, Земля и Юпитер , устанавливают свои собственные данные и передают их объекту базовой планеты.
  4. Объект планеты возвращает замыкание, которое содержит базовую функциональность. Дочерние классы получают это замыкание и добавляют к нему дополнительные методы и переменные.

Подъем 

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

mylocation = "dublin"; // global variable
function outputPosition() {
    console.log(mylocation);  // outputs "undefined" not "dublin"
    var mylocation = "fingal" ; 
    console.log(mylocation);  // outputs "fingal"
}
outputPosition(); 

В приведенной выше функции объявление var в функции означает, что первый журнал «увидит» mylocation в области действия функции, а не тот, который объявлен в глобальной области действия. После объявления локальная переменная mylocation будет иметь значение «undefined», поэтому сначала она выводится. Функции, которые назначены переменным, также могут быть подняты. Единственное отличие состоит в том, что когда функции поднимаются, их определения также — не только их объявления.

Непосредственные функциональные выражения

Непосредственные функциональные выражения выполняются, как только они определены.

(function() {

    console.log("I ain't waiting around");

}());

Здесь нужно отметить два аспекта синтаксиса. Во-первых, сразу после определения функции есть (), это заставляет ее выполняться. Во-вторых, функция может выполняться, только если она является выражением функции, а не объявлением функции. Функция external () делает функцию выражением. Другой способ определить непосредственное выражение функции:

var anotherWay = function() {
    console.log("I ain't waiting around");
}()

JSON

JavaScript Object Notation (JSON) — это нотация, используемая для представления объектов. Это очень похоже на формат, используемый для литералов Javascript Object, за исключением того, что имена свойств должны быть заключены в кавычки. Формат JSON не является эксклюзивным для javascript; он может использоваться любым языком (Python, Ruby и т. д.). JSON позволяет легко увидеть, что такое массив и что такое объект. В XML это будет намного сложнее. С внешним документом, таким как XSD, нужно будет ознакомиться. В этом примере у Митта Ромни есть массив, описывающий, кто может за него болеть, и объект, который является его сыном.

{"name": "Mitt Romney", "party": "republicans", "scary": "of course", "romneysMostLikelyVoters": ["oilguzzlers", "conservatives"], son : {name:'George Romney}}

Слабая типизация

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

var number1 = 50;
var number2 = "51";

function output(varToOutput) {
    // function does not care about what type the parameter passed is.
    console.log(varToOutput);
}
output(number1);  // outputs 50
output(number2);  // outputs 51

Мемоизация

Мемоизация — это механизм, посредством которого функции могут кэшировать данные из предыдущих выполнений.

function myFunc(param){
    if (!myFunc.cache) {
        myFunc.cache = {}; // If the cache doesn't exist, create it.
    }
    if (!myFunc.cache[param]) {
        //... Imagine the code to work out result below
        // is computationally intensive.
        var result = {
            //...
        };
        myFunc.cache[param] = result;  // now result is cached.
    }
    return myFunc.cache[param];
}

Метод

Когда функция сохраняется как свойство объекта, она называется методом.

var myObject {
    myProperty: function () {
       //...
       // the this keyword in here will refer to the myObject instance.
       // This means the "method" can read and change variables in the
       // object.
    }
}

Модули

Цель модулей — сделать базы кода JavaScript более модульными. Функции и переменные объединяются в модуль, и затем модуль может решать, какие функции
и какие переменные может видеть внешний мир — так же, как инкапсуляция работает в объектно-ориентированных парадигмах. В javascript мы создаем модули, комбинируя характеристики замыканий и непосредственные выражения функций.

var bankAccountModule = (function moduleScope() {
    var balance = 0; //private
    function doSomethingPrivate(){  // private method
        //...
    }  
    return { //exposed to public
        addMoney: function(money) {
             //...   
        },
        withDrawMoney: function(money) {
             //...
        },
        getBalance: function() {
            return balance;
    }
}());

В приведенном выше примере у нас есть модуль банковского счета:

  • Выражение функции moduleScope имеет свою область видимости. Закрытая переменная balance и закрытая функция doSomethingPrivate существуют только в этой области и видны только функциям в этой области.
  • Функция moduleScope возвращает литерал объекта. Это замыкание, которое имеет доступ к закрытым переменным и функциям moduleScope. Свойства возвращаемого объекта являются «общедоступными» и доступны для внешнего мира.
  • Возвращенный объект автоматически присваивается bankAccountModule
  • Синтаксис немедленной функции ()) используется. Это означает, что модуль инициализируется немедленно.

Поскольку возвращенный объект (замыкание) назначен для
bankAccountModule , это означает, что мы можем получить доступ к
bankAccountModule как:

bankAccountModule.addMoney(20);
bankAccoumtModule.withdrawMoney(15);

По соглашению, имя файла модуля должно соответствовать его пространству имен. Так что в этом примере имя файла должно быть bankAccountModule.js.

Шаблон пространства имен

Javascript не имеет встроенных в язык пространств имен, а это означает, что переменные легко конфликтуют. Если переменные не определены в функции, они считаются глобальными. Тем не менее, можно использовать «.» в именах переменных. То есть вы можете притворяться, что у вас есть пространства имен

DUBLINTECH.myName = "Alex"
DUBLINTECH.myAddress = "Dublin

Буквенное обозначение объекта

В javascript вы можете определить объект как набор пар имя-значение. Значения могут быть значениями свойств или функциями.

var ireland = {
    capital: "Dublin",
    getCapital: function () {
        return this.capital;
    }
};

Свойства прототипа (наследование)

Каждый объект имеет объект-прототип. Это полезно, когда вы хотите добавить свойство ко всем экземплярам определенного объекта. Предположим, у вас есть функция конструктора, которая представляет ирландцев, которые покупали в буме.

function IrishPersonBoughtInTheBoom(){
}

var mary = new IrishPersonBoughtInTheBoom ();
var tony = new IrishPersonBoughtInTheBoom ();
var peter = new IrishPersonBoughtInTheBoom ();
...

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

IrishPersonBoughtInTheBoom.prototype.debt = "ouch";

Потом…

console.log(mary.debt);   // outputs "ouch"
console.log(tony.debt);   // outputs "ouch"
console.log(peter.debt);   // outputs "ouch"

Теперь, когда этот подход используется, все экземпляры IrishPersonBoughtInTheBoom совместно используют сохраненную копию свойства долгов. Это означает, что все они имеют одинаковое значение, как показано в этом примере.

Возврат функций

Функция всегда возвращает значение. Если return не указан для функции,
будет возвращен
неопределенный тип значения. Функции Javascript также могут возвращать некоторые данные или другую функцию.

var counter = function() {
    //...
    var count = 0;
    return function () {
        return count = count + 1;
    }
}

var nextValue = counter(); 
nextValue();   // outputs 1
nextValue();   // outputs 2

Обратите внимание, что в этом случае возвращаемая внутренняя функция «
закрывается » над переменной count, делая ее
закрытой, поскольку она инкапсулирует свою собственную переменную count. Это означает, что он получает свою собственную копию, которая
отличается от переменной, возвращаемой
nextValue.count.

это ключевое слово

The
это ключевое слово в Java имеет различные значения в зависимости от
контекста оно используется . В итоге:

  • В контексте метода это относится к объекту, который содержит метод.
  • В контексте функции это относится к глобальному объекту. Если только функция не является свойством другого объекта. В этом случае это относится к этому объекту.
  • Если это используется в конструкторе, функция this в конструкторе ссылается на объект, который использует функцию конструктора.
  • Когда используются методы apply или call , значение этого относится к тому, что было явно указано в вызове apply или call.

typeof

typeof — унарный оператор с одним операндом. Он используется для определения типов вещей (немного похоже на getClass () в Java). Значения, выводимые typeof: «число», «строка», «логическое значение», «неопределенное», «функция», «объект».

console.log(typeof "tony");          // outputs string
console.log(typeof 6);               // outputs number
console.log(false);                  // outputs boolean
console.log(this.doesNotExist);   // outputs undefined if the global scope has no such var
console.log(typeof function(){});    // outputs function
console.log(typeof {name:"I am an object"});  //outputs object
console.log(typeof ["I am an array"]) // typedef outputs object for arrays
console.log(typeof null)              // typedef outputs object for nulls

Некоторые реализации возвращают «объект» для typeof для регулярных выражений; другие возвращают «функцию». Но самая большая проблема с typeof состоит в том, что он возвращает объект для нуля. Чтобы проверить на ноль, используйте строгое равенство …

if (myobject === null) {
    ...
}

Самопереопределение функций

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

var myFunction = function () {
    //set up code only to this once
    alert("set up, only called once");

    // set up code now complete.
    // redefine function so that set up code is not re-executed
    myFunction = function() {
         alert("no set up code");
    }
}
myFunction();  // outputs - Set up, only called once
myFunction();  // outputs - no set up code this time
myFunction();  // outputs - no set up code this time

Обратите внимание, что любые свойства, добавленные в настраиваемую часть этой функции, будут потеряны, когда функция переопределит себя. Кроме того, если эта функция используется с другим именем (т. Е. Она назначена переменной), повторное определение не произойдет, и код настройки будет выполнен повторно.

Область действия

В javascript есть глобальная область действия и область действия функции, доступная для переменных.
варКлючевое слово не нужно использовать для определения переменной в глобальной области видимости, но оно должно использоваться для определения переменной в локальной области действия функции. Когда переменная находится в области видимости, локальная функция разделяет имя с глобальной переменной, локальная область имеет приоритет — если var не использовался для объявления локальной переменной, и в этом случае любые локальные ссылки указывают на глобальную ссылку. В javascript нет области видимости блока. Под блоком мы понимаем код между {}, то есть фигурными скобками.

var myFunction = function () {
var noBlockScope = function ( ) {
    if (true) { 
        // you'd think that d would only be visible to this if statement
        var d = 24;   
    }
    if (true) {
        // this if statement can see the variable defined in the other if statement
        console.log(d); 
    }
}
noBlockScope();

Шаблон одной

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

function scrum() {
    var numberOfProps = 2,
        numberOfHookers = 1,
        numberOfSecondRows = 2,
        numberOfBackRow = 3
    // function body...
}

Если переменная объявлена, но не инициализирована значением, она будет иметь неопределенное
значение
.

Строгое равенство

В javascript можно сравнивать два объекта, используя ==. Однако в некоторых случаях это будет выполнять преобразование типов, которое может привести к неожиданным совпадениям равенства. Для обеспечения строгого сравнения (т.е. без преобразования типов) используйте
синтаксис
=== .

console.log(1 == true)    // outputs true
console.log(1 === true)   // outputs false
console.log(45 == "45")   // outputs true
console.log(45 === "45")  // outputs false

Правда и Ложь

Когда javascript ожидает логическое значение, вы можете указать значение любого типа. Значения, которые преобразуются в истину, называются правдивыми, а значения, которые преобразуются в ложные, называются ложными. Примером истинных значений являются объекты, массивы, функции, строки и числа:

// This will output 'Wow, they were all true'
if ({} && {sillyproperty:"sillyvalue"} && [] &&
        ['element'] && function() {} && "string" && 89) {
   console.log("wow, they were all true");
}

Примерами значений Falsey являются пустые строки, undefined, null и значение 0.

// This will out put: 'none of them were true'
if (!("" || undefined || null || 0)) {
    console.log("none of them were true");
}

Undefined и null

В javascript значение undefined означает не инициализированное или неизвестное, где null означает отсутствие значения.

Ссылки

  1. JavaScript шаблоны Стоян Стефанов
  2. JavaScript, полное руководство Дэвид Фланаган
  3. JavaScript, Хорошие запчасти Даг Крокфорд.