有没有办法包装jQuery的isArrayLike?

时间:2016-09-21 20:32:20

标签: javascript jquery monkeypatching

我试图处理XenForo和基本插件之间的冲突。我也不能直接修改代码。 jQuery 1.11.3是正在使用的版本,也无法升级。

我可以使用try / catch包装调用函数并避免冲突,但真正的修复将涉及使用try / catch包装jQuery的isArrayLike。

isArrayLike位于https://github.com/jquery/jquery/blob/master/src/core.js#L464

中第464行的(当前版本)jQuery源代码中

我需要捕获的内容似乎正是https://forum.jquery.com/topic/jquery-isarraylike-for-consistency中关于isArrayLike在传递无效类型时抛出错误的争论。

所以,既然jQuery的isArrayLike没有暴露,有没有办法包装它,或者最坏的情况,进入并替换它?

编辑:注意,到目前为止所有的评论都试图调试错误本身。那不是我的问题。我问是否有任何方法可以访问isArrayLike,所以它可以用另一个函数包装。

1 个答案:

答案 0 :(得分:2)

我建议更换jQuery eachmap方法,这些方法似乎是调用isArrayLike的唯一方法,但makeArray除外。但是我建议的修复对于后一种方法不是必需的。

添加:

(function ($, origEach, origMap) {
    $.each = function (elems, callback, arg) {
        return origEach.call(this, Object(elems), callback, arg);
    };
    $.map = function (elems, callback, arg) {
        return origMap.call(this, Object(elems), callback, arg);
    };
})(jQuery, jQuery.each, jQuery.map);

它改变了传递给mapeach的第一个参数:它被包含在Object调用中,当它是一个数组时它不会改变,但会转换参数一个对象,如果它不是一个对象(由于一些奇怪的原因)。

修补jQuery

如果您可以使用jQuery的修补版本,只需存储jQuery的副本,并在函数isArrayLike中修改此行:

var length = !!obj && "length" in obj && obj.length,

为:

var length = !!obj && "length" in Object(obj) && obj.length,

对于XenForo来说,这不应该是一个问题,只要您通过另一个script标记明确添加修补的jQuery,包含XenForo后的。最新的jQuery对象会覆盖前一个jQuery对象,因此XenForo也将使用修补版本,即使它包含非修补的jQuery库本身。

修补的缺点是你无法升级jQuery(隐式地使用XenForo升级),除非你每次升级时都修补它(直到不再需要它的版本)。

这是第一个解决方案所不具备的问题。