Лучший синтаксический сахар javascript

Вот несколько жемчужин:

Литералы:

var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');

По умолчанию:

arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';

Конечно, мы знаем анонимные функции, но возможность рассматривать их как литералы и выполнять их на месте (как закрытие) - это здорово:

(function() { ... })(); // Creates an anonymous function and executes it

Вопрос: Какой еще замечательный синтаксический сахар доступен в javascript?

Я не знал об этом || синтаксис значения по умолчанию. Красиво и компактно, хотя и не так интуитивно понятно. (Возможно, я имеют видел это, но так и не понял.)

Chris Noe 08.10.2008 04:37

Мне было намного труднее понять тернарный синтаксис. После того, как вы напишете это несколько раз, это будет казаться вашей второй натурой. Насколько вы могли это видеть, я думаю, что и jquery.js, и prototype.js используют его.

eyelidlessness 08.10.2008 06:06

Как насчет объяснения каждого из примеров?

pc1oad1etter 22.10.2008 05:35

Я не знал об "arg || 'default'". Я ожидал, что он вернет логическое значение, но он возвращает первое значение (слева), которое оценивается как истинное (аналогично python)! Это намного лучше, чем "arg = arg? Arg: 'default'"!

Jamol 28.12.2009 09:59

Крис Ноу заложил эту тему!

Mahesh Velaga 18.04.2010 05:52

Вы должны добавить в (function () {}) (); что он в основном используется для букмарклетов, поэтому браузер не будет перенаправлять на результат выражения lsat.

tstenner 19.08.2010 22:37

Синтаксис arg || 'default' также немного (на 15%) быстрее, я добавил здесь быстрый тест: jsperf.com/boolean-conditionals-vs-ternary

adamJLev 20.08.2010 19:35

аргумент || 'default' не работает, если вам нужен 'ложный' аргумент определенного типа. arg === undefined? по умолчанию: arg намного безопаснее.

Gregg Lind 23.11.2010 01:55

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

eyelidlessness 23.11.2010 03:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
81
9
12 812
30
Перейти к ответу Данный вопрос помечен как решенный

Ответы 30

В Mozilla (и, как сообщается, IE7) вы можете создать константу XML, используя:

var xml = <elem></elem>;

Вы также можете заменять переменные:

var elem = "html";
var text = "Some text";
var xml = <{elem}>{text}</{elem}>;

Действительно? Есть ли другие движки, которые это поддерживают?

eyelidlessness 08.10.2008 03:42

Просто интересно: что вы можете сделать с этой переменной "xml" после ее создания? Просто поиграв с ним сейчас в firebug, похоже, что у него нет никаких методов или свойств, и вы не можете добавить его в DOM.

nickf 08.10.2008 04:14

Полезная ссылка: developer.mozilla.org/index.php?title=En/…

Chris Noe 08.10.2008 04:23

Вы можете сделать это и в scala!

Steve g 10.10.2008 01:05

Rhino также поддерживает это (движок Javascript с открытым исходным кодом для Java): mozilla.org/rhino

J c 21.11.2008 16:25

@nickf: e4x великолепен !!! Некоторое время я использовал его с JSDB для вывода HTML-страниц и обработки XML. var x = <q> <a> b </a> </q>; x.a + = <a c="1"> cc </a>; x.a [0]. @ n = 3; для каждого (var c в x.children ()) print ("вау:" + c.toXMLString ()); (выводит это: wow: <a n="3"> b </a> wow: <a c="1"> cc </a>)

Jason S 09.12.2008 17:15

Литералы E4X представляют собой катастрофу для безопасности из-за атак с включением межсайтовых сценариев, и на самом деле не намного лучше, чем просто возможность сказать «var xml = new XML ('<elem> </elem>')» IMO.

bobince 07.03.2009 02:18

@bobince Если злоумышленник может внедрить Javascript, вы уйдете, независимо от того, включен ли E4X или нет

anonymous coward 08.02.2010 14:15

@CharlieSomerville Это не риск. E4X потенциально превращает "безопасные" [X] [HT] ML-файлы в активные JS. Пожалуйста, прочтите code.google.com/p/doctype/wiki/ArticleE4XSecurity для получения информации по этой проблеме.

bobince 08.02.2010 16:07

Используйте === для сравнения значения и type:

var i = 0;
var s = "0";

if (i == s)  // true

if (i === s) // false

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

olliej 08.10.2008 03:54

другие языки (PHP) также называют это «проверкой идентичности», то есть: являются ли эти два значения идентичный?

nickf 08.10.2008 04:15

@nickf, это неправильно. $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true, даже несмотря на то, что $var1 и $var2 не идентичны (ссылки на одно и то же сохраненное значение в памяти), это один и тот же тип и одно и то же значение.

eyelidlessness 18.12.2010 21:17

@eyelidlessness, я не уверен, что javascript так работает ... строки (как правило) хранятся и передаются по значению. Однако объекты хранятся как ссылка: var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.

nickf 19.12.2010 19:57

@nickf, я это понимаю. Но вы можете удалить сигил в коде PHP и получить тот же результат в JavaScript. Эти строки не идентичный, но их значения.

eyelidlessness 19.12.2010 23:40

Это не эксклюзивный javascript, но сохраняет как три строчки кода:

check ? value1 : value2

Есть ли аналог этого, если значение не присваивается (например, fnName? FnName: defaultFn;)?

eyelidlessness 08.10.2008 03:54

Нет, тернарный оператор предназначен только для выражений; нет заявлений

Josh Hinman 08.10.2008 04:11

вы можете использовать его для оценки анонимных функций, например: "var myFunc = (browserIsIE? function () {...}: function () {...})". лично я бы не рекомендовал это, так как это довольно запутанно, но, по крайней мере, это возможно.

nickf 08.10.2008 04:17

«оценивать», вероятно, не лучшее слово в предыдущем комментарии. Эмм .. назначить?

nickf 08.10.2008 04:23

@eyelidlessness: Да: fnName? fnName (): defaultFn (); // на отдельной строке, работает

Ates Goral 08.10.2008 05:11

Добавляя к моему комментарию выше, вы могли бы даже сделать: (fnName? FnName: defaultFn) ();

Ates Goral 08.10.2008 05:12

@Ates Goral: "работает", но выдает ошибку ReferenceError, если fnName не определено. Это вряд ли синтаксический сахар.

eyelidlessness 08.10.2008 06:16

Конечно, вы сделаете это только тогда, когда знаете, какие переменные будут объявлены. Вы даже можете пойти: (fnName || defaultFn)()

Ates Goral 20.08.2010 19:17

Еще немного на примере Левика:

var foo = (condition) ? value1 : value2;

Скобки не нужны. Тернарные операторы также характерны для многих других языков.

Ates Goral 08.10.2008 05:08

Скобки помогают при синтаксической неоднозначности условного оператора (например, при определении того, к какому компоненту условного оператора применяется знак?).

eyelidlessness 27.09.2009 10:45

Возможность расширять собственные типы JavaScript с помощью прототипного наследования.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}

Просто не делайте этого с массивом: stackoverflow.com/questions/61088/…

Chris Noe 08.10.2008 04:17

Это правда, но только если вы используете цикл for (a in b). Обычно я использую фреймворки, как, уверен, и все остальные. Как следствие, я обычно использую .each ()

steve_c 08.10.2008 04:35

Это потенциальная проблема, если код Любые в вашем контейнере использует for (a in b). И когда этот контейнер является браузером, вы можете нарушить другой код в своем браузере (например, этот фреймворк). Я был поражен этим.

Chris Noe 08.10.2008 04:42

Ага. Хорошие замечания, Крис. Я до сих пор считаю прототипное наследование одной из лучших особенностей JavaScript :)

steve_c 08.10.2008 04:52

for (var i in obj) {if (! obj.hasOwnProperty (i)) {продолжить; } ...}

eyelidlessness 08.10.2008 06:12

Да, вы всегда должны использовать hasOwnProperty, иначе цикл будет перебирать все свойства вверх по цепочке прототипов.

steve_c 13.10.2008 23:42

Это больше, чем метод расширения в .NET

linquize 21.05.2012 10:15

Многострочные струны:

var str = "This is \
all one \
string.";

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

Честное предупреждение - будет выдано исключение, если после \ будут конечные пробелы.

Daniel Szabo 13.05.2012 11:19

Использование анонимных функций и закрытия для создания частной переменной (скрытие информации) и связанных методов get / set:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()

заняло у меня мгновение, но я понял. это аккуратно.

matt lohkamp 09.10.2008 13:48

Я обнаружил похожую технику некоторое время назад, просматривая исходный код swfobject. Использование замыканий для создания частных переменных / методов - это то, о чем я, вероятно, никогда бы не подумал. Это круто.

Herms 31.03.2009 17:42

В новой версии JS мы можем использовать более простой if (true) { let _privateVar=123; }

Kulvar 16.11.2016 12:37

Помните о стилистической потенциальной проблеме "собачьих мячей". См .: twitter.com/paul_irish/status/176187448420864000?lang=en

Jonathan.Brink 01.06.2017 19:55

Тест на принадлежность к объекту:

var props = { a: 1, b: 2 };

("a" in props) // true
("b" in props) // true
("c" in props) // false

Это определенно более лаконично, чем props.a === undefined Спасибо.

eyelidlessness 08.10.2008 05:03

И это правда, даже если props = {a: undefined}.

ephemient 08.10.2008 07:09

К вашему сведению - Firefox выдает ошибку TypeError, когда вы пытаетесь использовать "in" в объекте XPCNativeWrapper. А начиная с Firefox 4 множество объектов обернуто. Так что вернемся к props.a === undefined в этих случаях.

Chris Noe 07.10.2011 18:28

Мне нравится иметь возможность eval () json-строки и получить обратно полностью заполненную структуру данных. Ненавижу писать все по крайней мере дважды (один раз для IE, снова для Mozilla).

Геттеры и сеттеры:

function Foo(bar)
{
    this._bar = bar;
}

Foo.prototype =
{
    get bar()
    {
        return this._bar;
    },

    set bar(bar)
    {
        this._bar = bar.toUpperCase();
    }
};

Дает нам:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"

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

Ash 11.10.2008 10:18

@eyelidlessness - это объект Object.defineProperty из ECMAScript 5, который реализует IE, а другие браузеры могут использовать defineGetter.

Eli Grey 15.08.2009 19:46

IE8 реализует геттеры / сеттеры только для объектов DOM, поэтому он бесполезен, когда дело доходит до создания более аккуратных собственных объектных API: - /

Jonny Buchanan 16.08.2009 00:57

Массив # forEach в Javascript 1.6

myArray.forEach(function(element) { alert(element); });

Я забыл:

(function() { ... }).someMethod(); // Functions as objects
Ответ принят как подходящий

Получение текущего даты и времени в миллисекундах:

Date.now()

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

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");

Фактически, это лучший синтаксический сахар javascript. Виннар - это ты.

eyelidlessness 22.10.2008 12:52

OrbMan, это, вероятно, зависит от контекста; если передать его в качестве аргумента, он может быть приведен к объекту, а не к числу или строке, и в этом случае знак + уже привел бы его к числу. Фактически, +, похоже, служит сокращением для parseInt (value, 10).

eyelidlessness 11.08.2009 04:33

Исправление: есть некоторые отличия от parseInt (value, 10). Например, + [3] и parseInt ([3], 10) равны числу 3, но + [3, 4] == NaN и parseInt ([3, 4], 10) == 3.

eyelidlessness 11.08.2009 04:37

Э ... все эти экземпляры parseInt (value, 10) должны быть parseFloat (value). И Крис Ноу, извините за спам в комментариях;)

eyelidlessness 11.08.2009 04:40

предупреждение (новая дата () + новая дата ()); // удваиваем годы с 0 года до настоящего момента.

Omar Al-Ithawi 16.11.2011 22:51

Мое любопытство подтолкнуло меня попробовать его в jsperf, и кажется, что наиболее производительным является канонический getTime () :) (ref. jsperf.com/millisecondsdate)

sirLisko 12.05.2012 14:16

Разве не лучше (или «слаще») просто определить функцию, чтобы можно было написать now()?

mhelvens 28.12.2013 17:13

Повторение строки, такой как «-», определенное количество раз, используя метод соединения для пустого массива:

var s = new Array(repeat+1).join("-");

Результат "---" при повторении == 3.

var tags = {
    name: "Jack",
    location: "USA"
};

"Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
    return tags[match];
});

обратный вызов для замены строки просто полезен.

int для строкового приведения

var i = 12;
var s = i+"";

Мне это не кажется более "сладким", чем выполнение прямого i.toString () или String (i). Коротко! = Сахар.

Ates Goral 20.08.2010 19:13

После obj || {default: true} синтаксис:

вызов вашей функции с помощью этого: hello (requiredOne && requiredTwo && needThree), если один параметр undefined или false, тогда он вызовет hello (false), иногда полезно

Назначение часто используемых ключевых слов (или любых методов) простым переменным, подобным этой

  var $$ = document.getElementById;

  $$('samText');

Это не сработает (по крайней мере, в Chrome), потому что значение this потеряно. Вместо этого вы должны использовать document.getElementById.bind(document). Без bind он просто назначает функцию HTMLDocument.prototype.getElementById без информации о том, что она должна вызываться на document.

pimvdb 31.08.2011 15:03

Изменить размер массива

Свойство length - это не только для чтения. Вы можете использовать его для увеличения или уменьшения размера массива.

var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.

Сэр, я считаю, что это должен быть самый важный ответ на SO. Мне больше не нужен push, хе-хе. Огромное спасибо.

aefxx 23.11.2010 03:29

на самом деле созданные таким образом элементы на самом деле не существуют (у них тоже нет значения undefined, но доступ к ним приведет к вам undefined). Вы также не можете перебирать их с помощью for..in.

yorick 19.01.2011 20:55

element.innerHTML = "";  // Replaces body of HTML element with an empty string.

Ярлык для удаления всех дочерних узлов элемента.

Это не совсем Javascript, это DOM, и в настоящее время он нестандартен.

eyelidlessness 02.09.2009 00:05

Класс Date в JavaScript, обеспечивающий полу- "Свободный интерфейс". Это компенсирует невозможность напрямую извлечь часть даты из класса Date:

var today = new Date((new Date()).setHours(0, 0, 0, 0));

Это не полностью свободный интерфейс, потому что следующее даст нам только числовое значение, которое на самом деле не является объектом Date:

var today = new Date().setHours(0, 0, 0, 0);

Резервный вариант по умолчанию:

var foo = {}; // empty object literal

alert(foo.bar) // will alert "undefined"

alert(foo.bar || "bar"); // will alert the fallback ("bar")

Практический пример:

// will result in a type error
if (foo.bar.length === 0)

// with a default fallback you are always sure that the length
// property will be available.
if ((foo.bar || "").length === 0) 

Как и оператор по умолчанию, || является оператором охраны, &&.

answer = obj && obj.property

в отличие от

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}

Это не обязательно должен быть null. Это только в случае, когда obj === null.

pimvdb 31.08.2011 14:59

Также может использоваться вместе с || для обеспечения резервного копирования в случае, если объект obj вообще не существует, ИЛИ объект существует, а свойство key - нет. Таким образом всегда определяется ответ: answer = (obj && obj.property) || 'backupprop';

Dtipson 30.06.2015 17:58

Создайте анонимный литерал объекта с помощью простого: ({})

Пример: нужно знать, есть ли у объектов метод valueOf:

var hasValueOf = !! ({}). valueOf

Дополнительный синтаксический сахар: двойное не "!!" для очень лаконичного преобразования почти всего в логическое значение.

В ситуациях парсинга с фиксированным набором комплектующих:

var str = "John Doe";

Вы можете присвоить результаты непосредственно переменным, используя synatx «деструктурирующее присвоение»:

var [fname, lname] = str.split(" ");
alert(lname + ", " + fname);

Что немного читабельнее, чем:

var a = str.split(" ");
alert(a[1] + ", " + a[0]);

Альтернативно:

var [str, fname, lname] = str.match(/(.*) (.*)/);

Обратите внимание, что это функция Javascript 1.7. Итак, на данный момент это браузеры Mozilla 2.0+ и Chrome 6+.

Я попробовал это в консоли Safari Javascript, и это привело к ошибке синтаксического анализа.

eyelidlessness 13.10.2010 01:18

Snap, думаю, я использовал это только в Firefox. Я добавил примечание о совместимости с браузером.

Chris Noe 13.10.2010 04:43

Не работает в Chrome 6. Отдает SyntaxError: Unexpected token [.

RaYell 13.10.2010 16:19

Небольшое исследование показывает, что версия Chrome 1.7 не совсем стандартная. Сообщается также о проблеме с let: stackoverflow.com/questions/300185/…

Chris Noe 15.10.2010 02:00

Он по-прежнему не работает в Chrome 13. Есть какие-нибудь подсказки относительно того, когда это будет реализовано?

pimvdb 31.08.2011 15:01

Мне нравится, как просто работать со списками:

var numberName = ["zero", "one", "two", "three", "four"][number];

И хеши:

var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];

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

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";

Выглядит потрясающе, каково это техническое название?

TrySpace 20.05.2014 12:20

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

a = b && b.length;

Это более короткий эквивалент:

a = b ? b.length : null;

Самое приятное то, что вы можете проверить цепочку свойств:

a = b && b.c && b.c.length;

Немедленно вызываемая стрелочная функция:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";

Преобразование строки в целое число, по умолчанию на 0, если это невозможно,

0 | "3" //result = 3
0 | "some string" -> //result = 0
0 | "0" -> 0 //result = 0

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

Литералы шаблона

var a = 10;
var b = 20;
var text = `${a} + ${b} = ${a+b}`;

тогда переменная текст будет такой, как показано ниже!

10 + 20 = 30

Другие вопросы по теме