在看一段代码的时候,怎么都不能理解作者的意图..., 这个abc是要做什么呢?
s = /abc/.test(function () {
abc
}) ? /\b_super\b/ : /.*/
源代码:
define("lang/Class", ["require", "exports", "module"], function (e, t, n) {
var r = n.exports = function () {
}, i = !0, s = /abc/.test(function () {
abc
}) ? /\b_super\b/ : /.*/;
r.extend = function (e) {
function t() {
i && this.init && this.init.apply(this, arguments)
}
var n = this, r = n.prototype;
i = !1, t.prototype = new n, t.prototype.constructor = t, t.extend = arguments.callee, i = !0;
var o = null;
for (name in e) {
if (!e.hasOwnProperty(name))continue;
o = e[name];
if (typeof o != "function" || typeof r[name] != "function" || !s.test(o)) {
t.prototype[name] = o;
continue
}
t.prototype[name] = function (e, t) {
return function () {
var n = this._super, i;
return this._super = r[e] || function () {
}, i = t.apply(this, arguments), this._super = n, i
}
}(name, o)
}
return t
}
})
有意思,翻了一下标准和 MDN 文档,发现 RegExp.prototype.test
并不能接收函数定义为参数,至少没有说明如果参数为函数定义会如何处理。
那么按照惯例,既然 RegExp.prototype.test
期望的参数是一个字符串,那么可以猜想解释器会调用 Function.prototype.toString
来转换传入的函数定义。那么问题来了:做这件事情的意义何在?
我没有细细看后面的代码(因为变量名混淆了,我看着头晕……),但是根据之前的分析,/abc/.test(function() { abc })
在正常情况下必然会返回 true
,所以 s
就会赋值为 /\b_super\b/
,否则会赋值为 /.*/
。
所以虽然还没有深入发掘这样做的确切目的,但可以看出这是一个有效性检查,就是为了检查 Function.prototype.toString
的行为是正常的。
@nightire 大神的思维太敏捷了!容我梳理玩整篇代码之后再来回顾这个问题