我尝试为 Object 创建一个 length() 方法原型,但破坏了 jQuery –如何?

发布于 2024-08-29 01:29:57 字数 248 浏览 3 评论 0原文

我写了以下内容:

Object.prototype.length = function(){
    var count = -1;
    for(var i in this) count++;
    return count;
}

它有效。但是当我执行页面时,即使不使用这个函数,Firebug 也会告诉我 jQuery 的 .appendTo() 不再是一个函数。为什么会这样呢?

I wrote the following:

Object.prototype.length = function(){
    var count = -1;
    for(var i in this) count++;
    return count;
}

It works. But when I execute my page, even without using this function, Firebug tells me that jQuery's .appendTo() is no longer a function. Why would this be?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜嗑 2024-09-05 01:29:57

该原型扩展正在破坏 $.each< /code>方法,因为此方法使用 length 属性检测数组和对象之间的关系(在 jQuery 1.4.2):

// core.js Line 533
each: function( object, callback, args ) {
    var name, i = 0,
        length = object.length, // <--- your function from Object.prototype
        isObj = length === undefined || jQuery.isFunction(object);
//...

如您所见,仅当 isObj 变量不包含 length< 时,它才为 true /code> 属性(或属性值为未定义)。

如果 isObj 为 false,jQuery 将尝试使用正常的 for 循环进行迭代:

for ( var value = object[0];
    i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}

然后,使用 $ 创建 appendTo 方法。每个,这就是为什么没有定义:

//...
jQuery.each({
    appendTo: "append",
    prependTo: "prepend",
    insertBefore: "before",
    insertAfter: "after",
    replaceAll: "replaceWith"
},
//...

当你扩展这个原型ALL始终建议远离扩展Object.prototype对象接收这些附加属性。

这是特别有问题的,因为当您迭代对象的属性时
这些新属性的出现会导致各种意外行为。

That prototype extension is breaking the $.each method, because this method detects between arrays and objects using the length property (in jQuery 1.4.2):

// core.js Line 533
each: function( object, callback, args ) {
    var name, i = 0,
        length = object.length, // <--- your function from Object.prototype
        isObj = length === undefined || jQuery.isFunction(object);
//...

As you can see, the isObj variable will be true only if it doesn't contains a length property (or the property value is undefined).

If isObj is false, jQuery will try to iterate using a normal for loop:

for ( var value = object[0];
    i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}

Then, the appendTo method is created using $.each, that's why is not defined:

//...
jQuery.each({
    appendTo: "append",
    prependTo: "prepend",
    insertBefore: "before",
    insertAfter: "after",
    replaceAll: "replaceWith"
},
//...

I will always recommend to stay away from extending Object.prototype, when you extend this prototype ALL objects receive those additional properties.

This is especially problematic since when you iterate over the properties of the object
these new properties appear, causing all sorts of unexpected behavior.

岁月打碎记忆 2024-09-05 01:29:57

这可能是因为 jQuery 的 .appendTo 依赖于(间接)Object.length,它是 JavaScript 中内置的,而不是函数。
如果您确实想将该方法添加到 Object,请将其命名为不会干扰预先存在的方法;类似 objLength 或 obj_length (或其他)的东西。
您还可以执行类似的操作来检查要添加到对象的属性是否已存在于该对象(直接从 Crockford 提升):

Object.prototype.method = function (name, func) {
    if (!this.prototype[name]){
        this.prototype[name] = func;
        return this;
    }
};

并像这样应用您的函数:

Object.method('myLength', function () {
    var count = -1;
    for (var i in this) {
        count += 1;
    }
    return count;
});

我知道我的循环在整个一个语句周围有括号,但它提高了可读性和可维护性。我听说这些都是好东西。

It's probably because jQuery's .appendTo depends (indirectly) on Object.length, which is builtin in JavaScript, and isn't a function.
If you really want to add that method to Object, call it something that won't interfere with pre-existing methods; something like objLength or obj_length (or whatever).
You can also do something like this to check if the attribute you want to add to an object already exists for that object (lifted straight from Crockford):

Object.prototype.method = function (name, func) {
    if (!this.prototype[name]){
        this.prototype[name] = func;
        return this;
    }
};

And apply your function like so:

Object.method('myLength', function () {
    var count = -1;
    for (var i in this) {
        count += 1;
    }
    return count;
});

And I know my loop has brackets around a whole one statement, but it improves readability and maintainability. I have heard those are good things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文