直接修改函数有多危险
How dangerous is modifying a function directly?
为了解决对我来说范围限制的问题(如这里所回答的),我编写了一段代码,在匿名函数中插入一行,这样编写函数的人就不必自己动手了。这有点古怪(实际上,感觉很古怪),我真的不知道自己在做什么,所以我很感激有一个专业的眼光来发现我可能错过的任何错误,或者指出我没有意识到的任何危险。这是代码:
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!
});
没人料到会有这样的恶作剧。
话虽如此,您的代码还有一些需要改进的地方:
CCD_ 4是用每一个新对象初始化的。这没有必要。更好地使用
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);
};
};
自从我在asp.net验证代码中看到这个方法以来,我一直被它困扰着(!)。对于任意函数来说并不安全:
var f = (function () {
var closure = 1
return function (argument) {
alert(argument)
alert(closure)
}
})()
var f2 = new Function(f.toString().replace(/^function.*?{(['s'S]*)}$/, 'alert(1);$1'))
f2(1) // :(
不过,可以保存参数。
相关文章:
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 将函数的上下文应用于javascript变量
- 如何在JavaScript中将字符串转换为函数引用
- 用嵌套函数和默认函数定义函数
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 无法导出函数expressjs/requestjs中的变量
- 函数参数中的数据与指定变量之间的任何性能差异
- JQuery合并了keyup和focusout两个函数
- ES6构造函数返回基类的实例
- 监视函数从服务返回不起作用,但作用域函数起作用
- 我可以在json对象中添加一个函数吗
- AngularJS:我可以跳过函数参数回调吗
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- JavaScript数组排序(函数)用于对表行进行排序,而不是排序
- jquery点击函数select&取消选择
- 拨打'父亲'函数形式a'儿童'ReactJS中的组件
- 直接修改函数有多危险
- 从危险的 SetInnerHtml 内容调用 React 类函数
- 在javascript中,使用回调函数递归地进行循环控制是很危险的
- 重写JavaScript对象和函数的危险