什么是JavaScript中的“断言”?


263

assertJavaScript是什么意思?

我看过类似的东西:

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

并想知道该方法的assert()作用。

Answers:


367

assertJavaScript 中没有(目前;谈论添加一个,但是它处于早期阶段)。也许您正在使用一些提供此功能的库。通常的含义是,如果传递给函数的表达式为false,则抛出错误;这是断言检查的一般概念的一部分。通常,断言(被称为断言)仅在“测试”或“调试”构建中使用,并从生产代码中删除。

假设您有一个应该始终接受字符串的函数。您想知道是否有人用不是字符串的函数调用了该函数。因此,您可以这样做:

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]具备)。


6
...对JS中的类型感到厌烦?我认为这是最糟糕的原因之一assert
cHao 2013年

137
@cHao:有有效的用例。这只是想到的第一个例子。例子不是重点。断言的概念很重要。
TJ Crowder

4
的东西,我已经添加到我的代码里面if(!condition)的设置var throwError=true;,然后debugger;再包裹扔节的if(throwError)。这样,如果我打开调试器,它将中断,并且如果我希望可以将其设置throwError为false,然后在退出时检查所有作用域。
里克(Rick)2015年

8
@Rick(如果您使用的是Chrome DevTools),则只需在“来源”标签中启用“暂停未捕获的异常”,它将在处自动中断throw。这样,您就无需debugger;声明。有关更多信息,请参见developer.chrome.com/devtools/docs/…
Vicky Chijwani,2015年

1
@machineghost:我不知道这是多么“简单”,您刚刚将其换成if条件运算符。无论如何,在当今世界上,我不会费心去支持那些没有的引擎Error
TJ Crowder

157

如果使用现代浏览器或nodejs,则可以使用console.assert(expression, object)

想要查询更多的信息:


46
仅供参考,这更像console.error是代码继续执行。
Daniel Sokolowski14年

10
@DanielSokolowski,是的。console.assert除非它具有与相同的行为,否则它并不是很好throw
Pacerier

23
之后继续执行的原因console.assert是因为断言不是错误处理函数。它们仅用于开发期间的代码正确性检查。传统上,它们在生产环境中被完全禁用,以避免活动系统由于琐碎的事情而终止。浏览器被视为生产环境,因此console.assert不会在此终止执行。如果您依靠断言停止执行,则应该改用适当的错误处理,因为这不是断言的目的。
Malvineous

8
@RonBurk:语言设计师决定“断言是什么意思”。在C ++中, [断言]用于捕获编程错误,而不是用户或运行时错误,因为通常在程序退出调试阶段后将其禁用。 PHP说,根据经验,如果未激活断言检查,则您的代码应始终能够正常运行。被动语态并不是要赋予个人偏爱以权威,而是要报告被广泛接受的普遍做法。
Malvineous

4
@唐:点了,但我只是从链接的页面引用。我确实认为,断言应该被视为可以被禁用,仅因为仅仅因为您的代码可能有一天被认为安全的人使用即可。如果断言对您的代码至关重要,那么我认为确实应该将断言升级为适当的错误检查,而不是依靠不一定总是保证终止执行的调试方法。更不用说让您的代码在生产环境中反复死亡的时候,它可能只是返回错误并继续执行,可能会带来更大的压力,这是不值得的!
Malvineous

29

其他答案很好:ECMAScript5中没有内置的断言功能(例如,基本上可在任何地方使用的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


顺便说一句,一个人可以很容易地修改它,使其仅在开发环境中引发错误(例如,如果在另一个环境中//添加另一个条件,则换行),否则不执行任何操作或仅显示警告。我个人认为断言只能在测试代码中进行(例如,检查预期结果与实际结果是否匹配);在生产代码它们要么应多余的(通过设计保证正确的),从而去除或仅守卫在这种情况下,它们可通过消毒逻辑标准异常处理(例如被替换用户/外部输入trycatchthrow
IX3

8

assert()不是本机javascript函数。这是某人自定义的功能。您将必须在页面或文件中查找它,并将其发布给任何人,以帮助确定它在做什么。


5

检查以下内容:http : //net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

它用于测试JavaScript。令人惊讶的是,在测试时,此代码仅用五到六行就能为您的代码提供强大的功能和控制力。

assert函数接受两个参数:

结果:一个布尔值,表示您的测试通过还是失败

描述:您的测试的简短描述。

然后assert函数简单地创建一个列表项,根据测试返回的是true还是false来应用“通过”或“失败”类,然后将描述追加到列表项。最后,该编码块被添加到页面中。疯狂的简单,但完美地运行。


4

这是一个断言函数的非常简单的实现。它带有一个值和要测试的内容的描述。

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

如果该值评估为true,则通过。

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

如果返回false,则失败。

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

1
断言的目的不是在信息级别登录到stdout,而是停止程序执行(通常引发异常),并且如果断言被评估为false,则登录到stderr。
NunoAndré18年

4

如果断言为假,则显示该消息。具体来说,如果第一个参数为false,则第二个参数(字符串消息)将记录在开发人员工具控制台中。如果第一个参数为true,则基本上什么也不会发生。一个简单的例子–我正在使用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.');


2

单词或函数“断言”通常用于测试应用程序的各个部分。

声明功能是指示程序检查条件的简短方式(也称为“声明”),如果条件不是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中不存在,而是JavaScript console.assert()中的assert函数。断言的目的是找出错误发生的原因/位置。

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函数的行,这对于调试没有用。


1

如果使用webpack,则只能使用node.js断言库。尽管他们声称它“不打算成为通用断言库”,但对于临时断言来说似乎还不错,而且Node空间中似乎也没有竞争对手(Chai专为单元测试而设计)。

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

您需要使用webpack或browserify才能使用此功能,因此显然,仅当工作流程中已包含这些功能时,此功能才有用。


1

除了console.assert自己滚动的其他选项外,您还可以使用invariant。它具有几个独特的功能:

  • 它支持格式化的错误消息(使用%s说明符)。
  • 在生产环境中(由Node.js或Webpack环境确定),错误消息是可选的,允许(略微)较小的.js。

0

如TJ所述,assertJavaScript中没有。但是,有一个名为assert的节点模块,主要用于测试。因此,您可能会看到类似以下的代码:

const assert = require('assert');
assert(5 > 7);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.