我正在尝试在 Javascript 中创建一个断言方法。我一直在与 argument.callee.caller 和朋友们斗争一段时间,但我找不到一种方法来可靠地获取调用函数的全文并找到调用当前函数的文本中的哪个匹配项。
我希望能够像这样使用我的函数:
var four = 5;
function calculate4() { return 6; }
assert(4 == 2 + 3);
assert(4 == four);
assert(4 == calculate4());
assert(4 != 3 && 2 < 1)
并获得这样的输出:
Assertion 4 == 2 + 3 failed.
Assertion 4 == four failed.
Assertion 4 == calculate4() failed.
Assertion 4 != 3 && 2
现在,除了 Assertion false failed.
之外我无法得到更多,这不是很有用......
我'我想避免传递额外的参数(例如 this
),因为我希望保持断言代码尽可能干净,并且因为它会被输入很多很多次。我真的不介意将其设为字符串,但我担心尝试 eval() 该字符串时的范围问题。如果我没有其他选择,或者我的担忧没有根据,请说出来。
我在 Windows 上的 .hta 应用程序中运行它,所以它实际上是 jscript,并且我可以完全访问文件系统、ActiveX 等,因此系统特定的解决方案很好(只要它们不需要 Firebug 等)。但是,我更喜欢通用的解决方案。
I'm trying to create an assert method in Javascript. I've been struggling with arguments.callee.caller and friends for a while, but I can't find a way to reliably get the full text of the calling function and find which match in that text called the current function.
I want to be able to use my function like this:
var four = 5;
function calculate4() { return 6; }
assert(4 == 2 + 3);
assert(4 == four);
assert(4 == calculate4());
assert(4 != 3 && 2 < 1)
and get output like this:
Assertion 4 == 2 + 3 failed.
Assertion 4 == four failed.
Assertion 4 == calculate4() failed.
Assertion 4 != 3 && 2
Right now, I can't get much beyond Assertion false failed.
which isn't very useful...
I'd like to avoid passing in extra parameters (such as this
) because I want to keep the assert code as clean as possible and because it will be typed many, many times. I don't really mind making it a string, but I'm concerned about issues of scoping when trying to eval() that string. If I have no other options, or if my concerns are ill-founded, please say so.
I'm running this in an .hta application on Windows, so it's really jscript and I have full access to the filesystem, ActiveX etc. so system specific solutions are fine (as long as they don't require Firebug etc.). However, I'd prefer a general solution.
发布评论
评论(3)
没有可靠的方法可以仅通过一个参数来完成此操作。即使使用
eval
,使用的变量也会超出范围。如果arguments.caller
仅通过搜索并解析参数表达式对assert
进行了一次调用,则解析arguments.caller
将会起作用。不幸的是,任何可用的专有工具都无济于事。There's no reliable way you can do this passing only a single argument. Even with
eval
, the variables used would be out of scope. Parsingarguments.caller
would work ifarguments.caller
made only one call toassert
, by searching for it and parsing the argument expression. Unfortunately, none of the proprietary tools available to you will help.我最终使用了以下函数,它允许我选择复制断言的文本作为第二个参数。这看起来很简单。
也许这对某人有帮助。可能有更好的方法可用,但这对我有用。
请注意,我只用 Javascript 编程了三天,因此可能还有许多可以改进的地方。
I ended up using the following function, which allows me to optionally duplicate the text of the assertion as a second argument. It seemed simplest.
Maybe that helps someone. There are probably better methods available, but this worked for me.
Note that I've only been programming in Javascript for three days, so there's probably a number of improvements that could be made.
实际上这是可能的,至少在浏览器和 Node.js 中是这样。我不了解 .hta 应用程序。
现代浏览器、Node.js 以及希望您的环境放置了
stack
属性,包含堆栈跟踪。您可以构造一个新错误,然后解析出包含assert()
调用的文件的文件路径,以及调用的行号和列号(如果有)。然后读取源文件,并在给定位置剪下assert
表达式。error
error.stack
,获取filepath
、lineNumber
和columnNumber
filepath
处的file
file
中lineNumber
和columnNumber
附近所需的位code>我已经编写了这样一个断言函数,名为 yaba,这可能会让您继续下去。
It is actually possible, at least in browsers and Node.js. I don't know about .hta applications.
Modern browsers, Node.js and hopefully your environment put a
stack
property on error objects, containing a stack trace. You can construct a new error, and then parse out the file path to the file containing theassert()
call, as well as the line number and column number (if available) of the call. Then read the source file, and cut out theassert
expression at the given position.error
error.stack
, to getfilepath
,lineNumber
andcolumnNumber
file
atfilepath
lineNumber
andcolumnNumber
infile
I've written such an assert function, called yaba, that might get you going.