为了解决已被证明是对我的范围限制的问题(如回答 here ),我编写了一段代码,在匿名函数中插入一行,这样编写该函数的人就没有自己做。这有点 hacky(实际上,感觉很 hacky),而且我真的不知道自己在做什么,所以我希望有专家的眼光来发现我可能遗漏的任何错误或指出我的任何危险我不知道。这是代码:
function myObj(testFunc) {
this.testFunc = testFunc;
this.Foo = function Foo(test) {
this.test = test;
this.saySomething = function(text) {
alert(text);
};
};
var Foo = this.Foo;
var funcSep = this.testFunc.toString().split("{");
funcSep.splice(0, 1);
funcSep = funcSep.join("{");
var compFunc = " var Foo = this.Foo;" + funcSep;
compFunc = compFunc.split("}");
compFunc.splice(compFunc.length - 1, 1);
compFunc.join("}");
var otherTestFunc = new Function(compFunc);
otherTestFunc.apply(this);
}
var test = new myObj(function() {
var test = new Foo();
test.saySomething("Hello world");
});
上面的函数按预期计算,我不需要强制编写匿名函数的人使用 this.Foo
获得对 Foo
的访问权限。不过,这种方法感觉不靠谱。我正在做的事情是否可以接受,如果不能,是否有任何方法可以规避它?
此外,我没有将其包含在我的原始问题中的唯一原因是这似乎与问题的原始上下文有所不同。
最佳答案
您正在尝试打破语言。不要那样做。这不是 Java。
开发人员对变量的行为和作用域有一定的期望,而你的做法宁愿混淆他们。考虑以下问题:
var Foo = SomeWonderfulClass;
var test = new myObj(function() {
var test = new Foo();
// ...
});
现在开发人员想要实例化 SomeWonderfulClass
,但您的魔法却弄乱了它。
另一方面,即使有你的诡计,这也能正常工作:
var test = new myObj(function() {
var Foo = SomeWonderfulClass;
var test = new Foo();
// ...
});
但更大的问题是实际范围丢失了:
var Bananas = SomeWonderfulClass;
var test = new myObj(function() {
var test = new Bananas(); // Error: Bananas is undefined!
});
没有人会想到这样的恶作剧。
话虽这么说,但您的代码有一些地方需要改进:
this.Foo
用每个新对象初始化。那没有必要。更好用myObj.prototype.Foo = function () {...}
myObj
中不需要行var Foo = this.Foo;
。您的字符串魔术过于复杂。怎么样
var otherTestFunc = new Function(testFunc.toString() .replace(/^[^{]+{/, '{var Foo=this.Foo;'));
无需取下牙套。
(
testFunc
不接受任何参数,但我想你知道这一点。)
所以这归结为
function myObj(testFunc) {
this.testFunc = testFunc;
var otherTestFunc = new Function(testFunc.toString()
.replace(/^[^{]+{/, '{var Foo=this.Foo;'));
otherTestFunc.apply(this);
}
myObj.prototype.Foo = function Foo(test) {
this.test = test;
this.saySomething = function(text) {
alert(text);
};
};
关于javascript - 直接修改函数有多危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11388747/