我可以复制/克隆 JavaScript 中的函数吗?
-
22-07-2019 - |
题
我将 jQuery 与验证器插件一起使用。我想用我自己的验证器替换“必需”验证器。这很容易:
jQuery.validator.addMethod("required", function(value, element, param) {
return myRequired(value, element, param);
}, jQuery.validator.messages.required);
到目前为止,一切都很好。这很好用。但我什么 真的 想要做的是在某些情况下调用我的函数,而在其余情况下调用默认验证器。不幸的是,这结果是递归的:
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods.required(value, element, param);
}, jQuery.validator.messages.required);
我查看了验证器的源代码,“required”的默认实现被定义为 jQuery.validator.messages.required 中的匿名方法。因此,我可以使用该函数,没有其他(非匿名)引用。
在调用 addMethod 之前在外部存储对函数的引用并通过该引用调用默认验证器没有什么区别。
我真正需要做的是能够按值而不是按引用复制默认所需的验证器函数。但经过相当多的搜索后,我不知道该怎么做。是否可以?
如果不可能,那么我可以复制原始函数的源代码。但这会产生维护问题,除非没有“更好的方法”,否则我宁愿不这样做。
解决方案
存储到函数的引用 外部调用addMethod前 并呼吁通过默认验证 该参考文献都没有区别。
这正是应该工作的。
jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods.oldRequired(value, element, param);
}, jQuery.validator.messages.required);
此应太:(并与this
问题解决)
var oldRequired = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return oldRequired.call(this, value, element, param);
// return jQuery.oldRequired.apply(this, arguments);
}, jQuery.validator.messages.required);
其他提示
Function.prototype.clone = function() {
var fct = this;
var clone = function() {
return fct.apply(this, arguments);
};
clone.prototype = fct.prototype;
for (property in fct) {
if (fct.hasOwnProperty(property) && property !== 'prototype') {
clone[property] = fct[property];
}
}
return clone;
};
与唯一不好的是,原型是不是克隆,所以你无法去改变它? 我工作的一种方式克隆任何类型的对象,我只是有正则表达式剩下要做。 所以,我可能明天编辑,并把整个代码(这是一种长的,如果你只使用它的功能和对象不是最佳的。
和评论其他答案,使用eval()是完全以愚蠢的方式太长,功能构造是一种相同的。 Literrals要好得多。 而包括只为那JQuery的,而且如果它不能正常工作(我不认为它)是不是你可以做的最聪明的事情。
下面是一个更新的答案
var newFunc = oldFunc.bind({}); //clones the function with '{}' acting as it's new 'this' parameter
然而.bind是JavaScript的一个新特征但有从MDN一种变通方法
https://developer.mozilla.org/en/JavaScript/参考/ Global_Objects /功能/绑定
此外它不克隆功能的其他属性。
注意:强>如图@gsnedder指出:结合的声明, “这个” 的说法ù供给(空白{}上文)。将持续的功能的任何未来的呼叫,而不管压倒经由应用()/()调用的功能。
这可能取决于你如何处理它均可使用你的优势,还是劣势。
我觉得你只是缺少一点作用域。尝试这样:
jQuery.validator.methods._required = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods._required.call(this, value, element, param);
}, jQuery.validator.messages.required);
(这应该只是一个评论 我可以复制/克隆 JavaScript 中的函数吗? ...不幸的是代表 < 50 只能发帖)
Function.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
就足够了,甚至
Object.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
关于效率的思考:
- 人的效率远比浪费人更重要 优化或改善机器“寿命”的资源
- 计算机和自动化系统应该减少人力 不增加它
- 计算开销必须严重影响结果的适口性 供人类消费,由许多人消费,以证明投资的合理性 努力优化代码,这些代码通常变得更加晦涩、晦涩难懂和 如此深奥,以至于它再也无法被稳定的 程序员在数小时试图“理解”逻辑后
关于克隆:这个问题可能很反讽
- “克隆”一个 javascript 对象意味着什么?特别是在递归函数理论的背景下
- 克隆合理化的一个共同主题是,它隔离并“保护”起源者免受其分身变化的影响
- 如果
a = new Object(); b = new Object();
是a
和b
克隆人?怎么样o = Object; a = new o(); b = new o();
- 真的需要吗?
- 克隆在哪里停止?是原型属性
隔离,因此克隆对象对这些的更改不会影响
实例未与克隆的对象关联?在这种情况下
克隆必须沿着原型链一直向上追溯到
原始构造函数,它们本身需要以某种方式
克隆和隔离(浏览器中的一个技巧是打开一个新窗口并用警告重新填充它
opener .
ETC。仍然可能泄漏交叉效应)
如果你想克隆功能,试试这个:
Function.prototype.clone=function(){
return eval('['+this.toString()+']')[0];
}
听起来像有没有“更好的方式”。我想你可以尝试做一个自定义所需的功能为自己的例如:
jQuery.validator.addMethod("customRequired", function(value, element, param) {
return myRequired(value, element, param);
}, jQuery.validator.messages.required);
听起来你已经尝试了一切。道歉,如果我误解的问题。
在回答以前的帖子,当我需要共享一个构造函数,同时保持鲜明的原型,我在一个新的功能使用包装:
`
init_from_arg_obj = function () {
return new Function('init', 'for (var i in init) this[i] = init[i];');
};
constructor_A = init_from_arg_obj();
constructor_A.prototype = {a: 'A'};
constructor_B = init_from_arg_obj();
constructor_B.prototype = {b: 'B'};
`
我运行几个测试来验证这确实良好的JS引擎不慢执行。