Что такое «утверждать» в JavaScript?

263

Что assertзначит в JavaScript?

Я видел что-то вроде:

assert(function1() && function2() && function3(), "some text");

И хотел бы знать, что assert()делает метод .

frrlod
источник

Ответы:

367

В assertJavaScript его нет (пока; говорят о его добавлении , но это на ранней стадии). Возможно, вы используете какую-то библиотеку, которая ее предоставляет. Обычный смысл - выбросить ошибку, если переданное в функцию выражение ложно; это часть общей концепции проверки утверждений . Обычно утверждения (как они называются) используются только в «тестовых» или «отладочных» сборках и удаляются из производственного кода.

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

assert(typeof argumentName === "string");

... где assertбы выкинуть ошибку, если бы условие было ложным.

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

function assert(condition, message) {
    if (!condition) {
        throw message || "Assertion failed";
    }
}

Еще лучше использовать Error объект, если движок JavaScript его поддерживает (на самом деле старые могут этого не ), что дает преимущество сбора трассировки стека и тому подобное:

function assert(condition, message) {
    if (!condition) {
        message = message || "Assertion failed";
        if (typeof Error !== "undefined") {
            throw new Error(message);
        }
        throw message; // Fallback
    }
}

Даже у IE8 есть Error(хотя у него нет stackсвойства, но у современных движков [включая современный IE] есть).

TJ Crowder
источник
6
... разобраться с типами в JS? Я бы сказал, что это одна из худших причин assert.
cHao
137
@CHao: Есть действительные варианты использования. Это был только первый пример, который пришел в голову. Пример не в этом. Понятие утверждений это точка.
TJ Crowder
4
то , что я добавил в мой код внутри if(!condition)устанавливает var throwError=true;то debugger;затем обернуть участок бросить в if(throwError). Таким образом, если у меня будет открыт отладчик, он сломается, и, если я так захочу, я могу установить throwErrorзначение false, а затем проверить все области при выходе.
Рик
8
@Rick, если вы используете Chrome DevTools, вы можете просто включить «Приостановить при невыполненных исключениях» на вкладке «Источники», и она автоматически сломается при throw. Таким образом, вам не нужно debugger;утверждение. См. Developer.chrome.com/devtools/docs/… для получения дополнительной информации.
Вики Чиджвани
1
@machineghost: я не понимаю, как это «проще», вы просто обменяли ifна условный оператор. Во всяком случае, в современном мире я бы не стал поддерживать двигатели, которые не имеют Error.
TJ Crowder
157

Если вы используете современный браузер или nodejs, вы можете использовать console.assert(expression, object).

Чтобы получить больше информации:

joaoprib
источник
46
К вашему сведению, это больше похоже console.errorна то, что код продолжает выполняться.
Даниэль Соколовский
10
@DanielSokolowski, именно так. console.assertне так хорошо, если он не имеет такое же поведение, как throw.
Pacerier
23
Выполнение продолжается после того console.assert, как утверждения не являются функциями обработки ошибок. Они предназначены для проверки правильности кода только во время разработки. Традиционно они полностью отключены в производственных средах, чтобы избежать прекращения работы живых систем из-за чего-то тривиального. Браузер считается производственной средой, поэтому console.assertего выполнение не прекращается. Если вы полагаетесь на утверждения, чтобы остановить выполнение, вам следует вместо этого использовать правильную обработку ошибок, поскольку это не то, для чего предназначены утверждения.
Malvineous
8
@RonBurk: дизайнеры языка решили, «для чего предназначены утверждения». В C ++ [утверждение] предназначено для захвата ошибок программирования, а не ошибок пользователя или времени выполнения, поскольку обычно оно отключается после выхода программы из фазы отладки. PHP говорит, как правило, ваш код всегда должен работать правильно, если проверка утверждений не активирована. Пассивный голос предназначался не для того, чтобы придать авторитет личным предпочтениям, а для того, чтобы сообщать о том, что является общепринятой общепринятой практикой.
Malvineous
4
@ Дон: Точка занята, но я просто цитировал со связанных страниц. Я верю, что к утверждениям следует относиться так, как будто они могут быть отключены, хотя бы потому, что когда-нибудь ваш код может быть использован кем-то, кто считает, что это безопасно. Если утверждения важны для вашего кода, то я думаю, что они действительно должны быть обновлены до надлежащей проверки ошибок, а не полагаться на метод отладки, который не всегда гарантирует прекращение выполнения. Не говоря уже о том, что ваш код неоднократно умирает в производственной среде, когда он может просто вернуть ошибку и продолжить, может вызвать больше стресса, чем оно того стоит!
Malvineous
29

Другие ответы хороши: в ECMAScript5 нет встроенной функции assert (например, JavaScript, который работает практически везде), но некоторые браузеры предоставляют ее вам или имеют надстройки, обеспечивающие эту функциональность. Хотя, вероятно, для этого лучше всего использовать хорошо зарекомендовавшую себя / популярную / поддерживаемую библиотеку, для академических целей функция «утверждение бедняка» может выглядеть примерно так:

const assert = function(condition, message) {
    if (!condition)
        throw Error('Assert failed: ' + (message || ''));
};

assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console
ix3
источник
Кстати, можно легко изменить это так, чтобы он только выдавал ошибку в средах разработки (например, путем переноса в другое, если / добавлял другое условное выражение), а в противном случае ничего не делал или только печатал предупреждение. Лично я считаю, что утверждения должны быть только в тестовом коде (например, проверка соответствия ожидаемых и фактических результатов); в рабочем коде они должны быть либо излишним (гарантируется правильная по конструкции) , и , таким образом , удалены или только для охраны пользователя / внешний вход , в этом случае они могут быть заменены на дезинфицирующего логику & стандартную обработку исключительных ситуаций (например try, catch, throw)
ix3
8

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

Crayon Violent
источник
5

Проверь это: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

это для тестирования JavaScript. Удивительно, что всего пять или шесть строк этого кода обеспечивают отличный уровень мощности и контроля над вашим кодом при тестировании.

Функция assert принимает два параметра:

результат: логическое значение, которое указывает, пройден ли ваш тест или нет

описание: краткое описание вашего теста.

Затем функция assert просто создает элемент списка, применяет класс «pass» или «fail», в зависимости от того, вернул ли ваш тест true или false, и затем добавляет описание к элементу списка. Наконец, этот блок кода добавляется на страницу. Это безумно просто, но работает отлично.

Amrendra
источник
4

Вот действительно простая реализация функции assert. Требуется значение и описание того, что вы тестируете.

 function assert(value, description) {
        var result = value ? "pass" : "fail";
        console.log(result + ' - ' +  description); 
    };

Если значение оценивается как истинное, оно проходит.

assert (1===1, 'testing if 1=1');  

Если он возвращает ложь, он терпит неудачу.

assert (1===2, 'testing if 1=1');
joshpierro
источник
1
Целью утверждения является не вход в stdout на информационном уровне, а остановка выполнения программы (обычно вызывает исключение) и вход в stderr, если утверждение оценено как ложное.
Нуно Андре
4

Если утверждение ложно, отображается сообщение. В частности, если первый аргумент равен false, второй аргумент (строковое сообщение) будет зарегистрирован в консоли инструментов разработчика. Если первый аргумент верен, в принципе ничего не происходит. Простой пример - я использую Google Developer Tools:

var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');
Сумасшедший кот
источник
3

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

http://chaijs.com/guide/styles/#assert

Мэтт Браун
источник
2

Слово или функция «assert» в основном используется при тестировании частей приложения.

Функции Assert - это короткий способ дать программе команду проверить условие (также называемое «утверждение»), и если условие не True, оно выдаст ошибку.

Итак, давайте посмотрим, как это будет выглядеть в «нормальном коде»

if (typeof "string" === "array") { throw Error('Error: "string" !== "array"'); }

С помощью assertможно просто написать:

assert(typeof "string" === "array")

В Javascript нет родного assert функции, поэтому вы должны использовать ее из какой-то библиотеки.

Для простого введения вы можете проверить эту статью:

http://fredkschott.com/post/2014/05/nodejs-testing-essentials/

Я надеюсь, что это помогает.

Павел
источник
2

Утверждение выдает сообщение об ошибке, если первый атрибут имеет значение false, а второй атрибут - это выбрасываемое сообщение.

console.assert(condition,message);

Есть много комментариев, в которых говорится, что утверждение не существует в JavaScript, но console.assert()является функцией assert в JavaScript. Идея утверждения состоит в том, чтобы выяснить, почему / где возникает ошибка.

console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");

Здесь, в зависимости от сообщения, вы можете найти ошибку. Эти сообщения об ошибках будут отображаться на консоли красным цветом, как если бы мы звонили. console.error();
Чтобы увидеть больше функций в консоли, выполнитеconsole.log(console);

Рахул
источник
1

Предыдущие ответы могут быть улучшены с точки зрения производительности и совместимости.

Проверьте один раз, существует ли Errorобъект, если не объявите его:

if (typeof Error === "undefined") {
    Error = function(message) {
        this.message = message;
    };
    Error.prototype.message = "";
}

Затем каждое утверждение проверяет условие и всегда выбрасывает Errorобъект

function assert(condition, message) {
    if (!condition) throw new Error(message || "Assertion failed");
}

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

Karl.S
источник
1

Если вы используете Webpack, вы можете просто использовать Node.js библиотеку утверждения . Хотя они утверждают, что это «не предназначено для того, чтобы быть библиотекой утверждений общего назначения», кажется, что это более чем нормально для специальных утверждений, и кажется, что в любом случае в пространстве Node нет конкурента (Chai предназначен для модульного тестирования).

const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");

Вы должны использовать webpack или browserify, чтобы иметь возможность использовать это, поэтому очевидно, что это полезно, только если они уже есть в вашем рабочем процессе.

amoe
источник
1

В дополнение к другим параметрам, таким как console.assert или собственным , вы можете использовать invariant . У этого есть несколько уникальных особенностей:

  • Он поддерживает отформатированные сообщения об ошибках (используя %s спецификатор).
  • В производственных средах (как определено средой Node.js или Webpack) сообщение об ошибке является необязательным, допуская (немного) меньший размер .js.
Джош Келли
источник