سؤال

لقد أضفت بسيطة .js ملف إلى صفحتي التي تحتوي على بعض الوظائف ذات المهام الشائع الدنيوي الدنيوي Object و Array نماذج النماذج.

من خلال التجربة والخطأ، لقد اكتشفت أن إضافة أي وظيفة إلى Object.prototype, ، بغض النظر عن اسمه أو ما يسبب أخطاء JavaScript في JQuery:

الجاني؟

Object.prototype.foo = function() {
    /*do nothing and break jQuery*/
};

الخطأ الذي أحصل عليه 1056 من jquery-1.3.2.js, ، في العنوان: وظيفة {} إعلان:

/*Object doesn't support this property or method*/
name = name.replace(/-([a-z])/ig, function(all, letter) {
            return letter.toUpperCase();
        });

على ما يبدو g.replace غير محدد.

في حين أنه من الواضح أن هناك شيئا ما لا أفتغاه لرئيسي حول النماذج الأولية، فأنا أفشل بشكل كبير لمعرفة ما هو عليه.

لتكون واضحة، أنا لا أبحث عن حلوة، ولدي هذا التعامل مع ... ما أبحث عنه هو إجابة على لماذا ا؟. وبعد لماذا يضيف وظيفة إلى Object.prototype كسر هذا القليل من التعليمات البرمجية؟

هل كانت مفيدة؟

المحلول

يجب أن لا تمتد أبدا Object.prototype. وبعد يفعل أكثر بكثير من كسر jquery؛ يكسر تماما ميزة "كائنات الحاشات القضائية" من جافا سكريبت. لا تفعل ذلك.

يمكنك أن تسأل جون ريسج، وسيقول لك نفس الشيء.

نصائح أخرى

إذا كانت مجرد حالة من العبث ... في الحلقات، فلا يمكنك استخدام Object.defineProperty لإضافة FN الخاص بك دون إجراء تعداد؟

وبالتالي:

Object.defineProperty(Object.prototype, "foo", { 
    value: function() {
        // do stuff
    },
    enumerable : false
});

يبدو أن العمل بالنسبة لي. هل لا يزال هذا يعتبر شكل سيء؟

أوافق، مضيفا شيئا ل Object.prototype مطالب الحذر وينبغي تجنبها. ابحث عن حلول أخرى مثل:

إضافة ذلك إلى الكائن ثم الوصول إليها مع call أو apply, ، كما هو مطلوب. علي سبيل المثال:

Object.foo = function () { return this.whatever()}

ثم اتصل بهذا على كائن عن طريق:

Object.foo.call(Objname);  // this invokes the function as though it were a
                           // method of Objname.  That is, its like Objname.foo()

للمتعة، يمكنك إضافة ما يلي (نعم، أعرف أنه خطير بعض الشيء ...):

Function.using = Function.call; // syntactic sugar

الآن يمكنك الكتابة Object.foo.using(Objname) ويقرأ مثل عقوبة.

ولكن كقاعدة عامة، ابتعد عن تغيير أي من النماذج النماذج الكبيرة.

لقد اخترقت رأسي حول هذه المشكلة حيث كنت ترغب في تنفيذ اتجاه كائن "حقيقي" في جميع كائناتي، مثل هذا:

interface Object
{
    GetType: () => string;
    ToString: () => string;
    GetHashcode: () => number;
    Equals: (obj: any) => boolean;
}

منذ كائن .protinePotine فاصل jQuery، لقد تم التنسج إلى الحل المشوي للاستفادة من تحديد بروبيرت ولكن هذا لا يأخذ أي حجج.

والخبر السار هو أنه يمكنك الاختراق في تحديد بروبيريا وقبول المعلمات بالفعل. هنا هو تطبيقي:

Object.defineProperty(Object.prototype, "Equals",
    {
        value: function (obj: any)
        {
            return obj == null && this == null
                    ? true
                    : obj != null && this == null
                        ? false
                        : obj == null && this != null
                            ? false
                            : this.GetHashcode() == obj.GetHashcode();
        },
        enumerable: false
    });

هذا يعمل ولا يصطاد مع jQuery.

أشك في إضافة وظيفة إلى كائن. ما عليك سوى تأكيد كل حلقة لديك في جميع أنحاء موقعك ملفوفة في فحص hasawnproproperty، لأنك تضيف الوظيفة على مستوى العالم ونتيجة للتكرار يمكن أن تكون غير متوقعة:

Object.prototype.foo = function() {};    
var myObject = {m1: "one", m2: "two" };

for(var i in myObject) { if(myObject.hasOwnProperty(i)) {
   // Do stuff... but not to Object.prototype.foo
}}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top