سؤال

لذلك كنت من خلال معظم الأسئلة هنا. أيضا عدد قليل جدا من المواد جيدة والسيئة.

شيء واحد أبحث عن بعض التوضيحات الإضافية حول كيفية معالجة المتغيرات غير المعروفة وغير الأمم المتحدة.

خذ الرمز أدناه.

var a;

if(a == null) // True - Due to Type Coercion

if(a == 'null') // False

if(a === null) // False

if(a === 'null') // False

if(a == undefined) // True

if(a === undefined) // True

if(a == 'undefined') // False

if(a === 'undefined') // False

if(a) // False - A is undefined

alert(typeof(a)) // undefined

كل ما سبق أفهمه. لكن الأمور تصبح غريبة عندما تنظر إلى متغير غير محدد. لاحظ أنني حذفت على وجه التحديد "فار ب"؛

 alert(typeof(b)) // undefined

 if(typeof(b) == 'undefined') // True

 if(typeof(b) === 'undefined') // True - This tells me the function typeof is returning a string value

 if(typeof(b) == 'null') // False

 if(typeof(b) === 'null') // False

 if(typeof(b) == null) // False

 if(typeof(b) === null) // False

 if(b) // Runtime Error - B is undefined

أي عملية أخرى ثم TypeOf (B) النتائج في خطأ وقت التشغيل. ما زلت أستطيع أن أفهم المنطق وراء الطريقة التي يقوم بها المقلية بتقييم التعبيرات.

حتى الآن أنا أنظر إلى ملكية غير موجودة من A و AM Confused.

if(a.c) // Runtime Error - c is null or not an object
alert(typeof(a.c)) // Runtime Error - undefined is null or not an object

أعتقد أن ج في هذه القضية سيتم التعامل معها مثل B في المثال السابق ولكن ليس كذلك. يجب عليك فعلا تهيئة شيء إلى شيء، ثم يمكنك الحصول عليه أن تتصرف كما B لا. وإيقافها من رمي أخطاء وقت التشغيل.

لماذا هذا هو الحال؟ هل هناك بعض التعامل مع نوع خاص من النوع غير المحدد أو هو وظيفة TypeOf القيام بشيء متكرر لتقييم الخاصية الفرعية التي ترمي خطأ وقت التشغيل؟

  1. أعتقد أن السؤال العملي هنا هو إذا قمت بالتحقق من كائن متداخلا C في AC، يمكنني أن أفترض على الفور C هو غير محدد إذا لم يتم تعليقه؟

  2. وما هي أفضل طريقة إذا أردت التحقق من بعض الكائن المتداخلة للغاية لمعرفة ما إذا كان تم تعيينه مثل x في myoBject.something.something.something.x؟ لا بد لي من التنقل عبر عنصر الهيكل حسب العنصر التأكد من أن كل واحد موجود قبل الذهاب إلى واحد التالي في السلسلة؟

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

المحلول

يمكنني أن أفترض على الفور هو غير محدد إذا لم يتم تعليقه؟

نعم.

يجب أن أتنقل من خلال عنصر الهيكل حسب العنصر التأكد من أن كل واحد موجود قبل الذهاب إلى واحد القادم في تشانين؟

نعم.

نصائح أخرى

السبب

alert(typeof(a.c))

النتائج في خطأ وقت التشغيل و

alert(typeof(b))

لا هو أنه في المثال الأول، تحاول الوصول إلى خاصية على كائن غير محدد، مما يؤدي إلى خطأ وقت التشغيل قبل يمكن تغذية النتيجة typeof()

لا تنسى undefined هو المتغير العالمي (!)، ويمكنك (أو شخص آخر) تعيينها قيمة، لذلك يمكن أن يكون مثالك مخطئا هنا:

if(a == undefined) // True

if(a === undefined) // True

إذا كنت بحاجة حقا إلى غير محدد، فيمكنك الحصول على "نسخ" الخاص بك

var local_undefined;

عادة لن تأتي عبر الحاجة اختبار الى ابعد حد (أكثر من ثلاثة مستويات) كائن متداخلا حيث أي من الوالدين يمكن أن يكون undefined. وبعد لذلك عندما تحتاج إلى اختبار، أود أن أكتبها شيء مثل هذا:

if( typeof(a) != 'undefined' && a.c ) {
   // Do something won't run because a is undefined
}

var a = {};

if( typeof(a) != 'undefined' && a.c ) {
   // Do something won't run because though a is defined,
   // a.c is undefined. This expression tests to see if a.c evaluates
   // to true, but won't throw an error even if it is 
   // undefined.
}

إذا a.c يمكن في أي وقت 0 أو false لكنك لا تزال بحاجة إلى اختبار المرور، ثم استخدم كامل typeof اختبار:

var a = {};
a.c = false;

if( typeof(a) != 'undefined' && typeof(a.c) != 'undefined' ) {
   // Do something will run because though both a and a.c are defined.
}

جافا سكريبت غريب في هذه القيمة undefined (أيضا typeof a === "undefined") هو ما المتغيرات حتى يتم إعطاء قيمة. null هي قيمة مميزة مختلفة عن undefined. وبعد نظرا لأن نظام النوع في JavaScript يفقد، فهناك إكراه نوع ضمني يحدث عند مقارنة وقيم الاختبار للمتغيرات.

إذا لم يتم تحديد متغير، فلن تتمكن من الرجوع إليها دون أخطاء ولكن يمكنك اختبارها مع typeof المشغل (ونتائجها ستكون السلسلة "undefined"). متغير تم الإعلان عنه ولكن لم يتم تعيينه قادر على الإشارة إليه ولكن لا يزال يحتوي على القيمة undefined. وبعد يمكنك دائما الرجوع إلى خصائص الكائنات غير المحددة وإذا لم يتم تعيينها ثم سيكون لديهم القيمة undefined.

انظر هذه الإجابة أيضا كما ذهبت إلى تفاصيل حول إكراه نوع JavaScript والقيم المختلفة التي غالبا ما تكون مفيدة للنظر فيها فارغة:

هل يتمتع ISPEMTY في VBScript بما يعادل جافا سكريبت؟

  1. عند اختبار كائنات متداخلة، إذا كان الوالد undefined (أو null) ثم ليس له أطفال حتى لا يتم حاجة إلى مزيد من الاختبارات.

  2. لاختبار بأمان كائن متداخلا، ستحتاج إلى اختبار الوالد الأعلى باستخدام typeof ولكن يمكنك اختبار أي أطفال للقيم الفعلية (انظر الاختبار للإجابة الفارغة). وذلك لأن المستوى العلوي قد لا يتم الإعلان عنه، ولكن يمكنك دائما الرجوع إلى خصائص غير محددة للكائنات.

بالنسبة متداخلة للغاية الأطفال

try{ if(a.b.c.d.e) {
    // do your stuff
}}catch(e){}

جرب الصيد الطريق هو حل أكثر أناقة وأقل ترميز النوع

وهنا مثال:

grand=""
a={ b:{ c:{ d:{ e:"Hello Ancestor" } } } }

try{ if(a.b.c.d.e) {
    grand = a.b.c.d.e
}}catch(e){}

alert( grand )

فقط نلقي نظرة على طريقة نوع مملة:

if(typeof a === undefined) {
    if(typeof a.b === undefined) {
        if(typeof a.b.c === undefined) {
            if(typeof a.b.c.d === undefined) {
                if(typeof a.b.c.d.e === undefined) {
                    // your stuff
                }
            }
        }
    }
}

قد يكون ذلك حلا أكثر أناقة ومثالية بعد التغلب على كتلة TRY-CAST في دالة، ومع ذلك، لا توجد طريقة معروفة لاستبدال اسم متغير مرجعي، والذي يمكن تمريره ك "سلسلة" لوظيفة، مع محتويات متغيرة. على سبيل المثال فيما يلي غير ممكن:

function isDefined(v) {
    if (typeof valueOfVar(v) !== undefined)
        return true
    else
        return false
}
alert( isDefined('a.b.c.d.e') ) // must be passed as a string to avoid runtime error

لا يوجد ValueOFVAR () موجود في JavaScript، هذا مجرد مثال


لكن تخمين ما، لقد حصلت على مسير، شرير المحلول :)

// a={ b:{ c:{ d:{ e:0 } } } }

function exist(v) {
    var local_undefined
    try{ if( eval(v) !== local_undefined ) {
        return true
    }}catch(e){}
    return false
}
alert( exist('a.b.c.d.e') )

تحديث مهم للمجديين () وظيفة - اثنين من الوظائف الإضافية التي تستخدمها ()

هذه تغطي كل ما هو مطلوب من أي وقت مضى لاختبار ما إذا كان متغير / الخاصية / كائن في أي مستوى التعشيش يكون محددة / فارغة / غير معلن دون التسبب في ظهور خطأ في وقت التشغيل في جافا سكريبت

function exists (v) {
    var local_undefined;
    try{ if( eval(v) !== local_undefined ) {
        return true
    }}catch(e){}
    return false
}

function empty (v) {
    if (exists(v)) {
        v = eval(v);
        if (typeof v == 'object') {
            return Object.keys(v).length === 0
        } else if (v)
            return false
    }
    return true
}

function value (v) {
    var local_undefined;
    if (exists(v))
        return eval(v)
    return local_undefined
}


/////////////////////////////////////////
// TEST

ref = 'a.b.c.d.e';

alert( ref +' : '+ value(ref) + '\n'
        + '\nexists\t' + exists(ref)
        + '\nempty\t' + empty(ref)
        + '\nvalue\t' + value(ref)
    );

a = { b:{ c:{ d:{ e:"Hello Ancestor" } } } };
alert( ref +' : '+ value(ref) + '\n'
        + '\nexists\t' + exists(ref)
        + '\nempty\t' + empty(ref)
        + '\nvalue\t' + value(ref)
    )

a = { b:{ c:{ d:{ e:0 } } } };
alert( ref +' : '+ value(ref) + '\n'
        + '\nexists\t' + exists(ref)
        + '\nempty\t' + empty(ref)
        + '\nvalue\t' + value(ref)
    );

b='a'; obj={a:5}; ref='obj[b]';
alert( ref +' : '+ value(ref) + '\n'
        + '\nexists\t' + exists(ref)
        + '\nempty\t' + empty(ref)
        + '\nvalue\t' + value(ref)
    );

ومع ذلك، فإن هذه الأساليب تعمل فقط عندما exists() empty() value() تتمتع الوظائف بالوصول إلى هذه المتغيرات، أي تعريف كل من الوظيفة والمتغيرات في نفس النطاق.

من الضروري أن تكون قادرا على اختبار متغيرات الوظائف المحلية أيضا، وإلا فإن متغيرات الوظائف المحلية التي تم الإعلان عنها var ستكون undefined في دعا exists() empty() value() وظيفة

لاختبار المتغير المحلي للدالة دون بما في ذلك exists() empty() value(), ، ال try/catch يجب استخدام كتلة داخل هذه الوظيفة


هنا بديل شرير حل لاختبار متغيرات الوظيفة المحلية يمكن تعريف مقتطفات التعليمات البرمجية هذه في نطاق عالمي ثم تم استدعاؤه باستخدام EVIV ()

is_ = "v_='"
var_ = "v_='"
get_ = "v_='"
set_ = "v_='"

_exists = "';\nvar local_undefined;\n"
        + "try{ if( eval(v_) === local_undefined ) false; else true }\n"
        + "catch(e){false}\n"

_empty = "';\nif ( eval(\"'\"+_exists) ) {\n"
        + " v_ = eval(v_);\n"
        + " if (typeof v_ == 'object') {\n"
        + "     Object.keys(v_).length === 0;\n"
        + " }\n\telse if (v_)\n"
        + "     false;\n"
        + " else true\n"
        + "} else true"

_value = "';\nif ( eval(\"'\"+_exists) )\n"
    + " eval(v_);\n"
    + "else local_undefined"

_valOrEmpty = "';\n( eval(\"'\"+_exists) )\n"
    + " ? eval(\"'\"+_value) : ''"

_valOrDefault_ = "';\n( eval(\"'\"+_exists) )\n"
    + " ? eval(\"'\"+_value) : "

function f() {
    var a = { b:{ c:{ d:{ e:"Hello Ancestor" } } } };
    ref = 'a.b.c.d.e'
    alert( ref+'\n'   
        +'\nexists\t\t'     + eval(is_  +ref+ _exists)
        +'\nempty\t\t'      + eval(is_  +ref+ _empty)
        +'\nvalue\t\t'      + eval(get_ +ref+ _value)
        +'\n'
        +'\nvalOrEmpty\t'   + eval(get_ +ref+ _valOrEmpty)
        +'\nvalOrDefault\t' + eval(get_ +ref+ _valOrDefault_ +'"Default Value"')
        )
}

d=""; while (d.length < 20) d="—"+d; d="\n\n// "+d+"\n// "
jsCode  ='// ( is_  +var+ _exists )\n\n'                + is_ +'a.b.c.d.e'+_exists
        +d+' ( is_  +var+ _empty )\n\n'                 + is_ +'a.b.c.d.e'+_empty
        +d+' ( get_ +var+ _value )\n\n'                 + get_+'a.b.c.d.e'+_value
        +d+' ( get_ +var+ _valOrEmpty )\n\n'            + var_+'a.b.c.d.e'+_valOrEmpty
        +d+' ( get_ +var+ _valOrDefault_ default )\n\n' + var_+'a.b.c.d.e'+_valOrDefault_+"'Default Value'"

alert(jsCode)

f()
// even though that looks ugly, this is the tidiest solution
// to the awkward 17-year old JavaScript error-handling

استخدم هذا بحكمة

if ( eval(is_  +'any.var.or.property.from.local.or.global.scope'+ _exists) ) {
    // do your stuff
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top