الذي يساوي المشغل(== vs===) يجب أن يستخدم في مقارنات JavaScript؟



operators equality (24)

لاغية وغير محددة هي العدم ، وهذا هو ،

var a;
var b = null;

هنا aو bليس لدينا القيم. بينما ، 0 ، false و "" كلها قيم. شيء واحد مشترك بين جميع هذه هي أنها كلها قيم كاذبة ، مما يعني أنها جميعا تفي بشروط كاذبة.

لذا ، فإن الصفر ، و "معا" يشكلون مجموعة فرعية. ومن ناحية أخرى ، شكل غير معروف وغير محدد المجموعة الفرعية الثانية. تحقق من المقارنات في الصورة أدناه. لاغية وغير معرفة على قدم المساواة. الثلاثة الآخرين يساوي بعضهم البعض. ولكن ، يتم التعامل معهم جميعًا كظروف مزعجة في جافا سكريبت.

هذا هو نفس أي كائن (مثل {} ، المصفوفات ، إلخ.) ، السلسلة غير الفارغة & Boolean true كلها شروط صادقة. لكن ، كلهم ​​ليسوا متساوين.

أنا أستخدم JSLint للانتقال عبر جافا سكريبت ، وهو يعيد العديد من الاقتراحات ليحل محل == (علامتين idSele_UNVEHtype.value.length == 0 ) مع === (ثلاث علامات متساوية) عند القيام بأشياء مثل مقارنة idSele_UNVEHtype.value.length == 0 داخل if بيان.

هل هناك فائدة من الأداء لاستبدال == مع === ؟

سيتم الترحيب بأي تحسين للأداء حيث يوجد العديد من مشغلي المقارنة.

إذا لم يحدث أي تحويل من نوع ، فهل سيكون هناك زيادة في الأداء على == ؟


Answer #1

في نص عادي ، لن يكون هناك فرق في الأداء. الأهم من ذلك هو حقيقة أن ألف "===" هو 1 كيلوبايت أثقل من ألف "==" :) يمكن لأدوار جافا سكريبت أن تخبرك ما إذا كان هناك اختلاف في الأداء في حالتك.

لكن أنا شخصياً أفعل ما تقترحه JSLint. لا توجد هذه التوصية بسبب مشكلات في الأداء ، ولكن لأن قسرية الكتابة تعني ('\t\r\n' == 0) صحيحة.


Answer #2

لماذا == لا يمكن التنبؤ بها؟

ما الذي تحصل عليه عندما تقارن سلسلة فارغة "" بالرقم صفر 0 ؟

true

صحيح ، وهذا صحيح وفقا ل == سلسلة فارغة ورقم الصفر هي في نفس الوقت.

ولا تنتهي هناك ، وهنا واحد آخر:

'0' == false // true

الامور حقا غريبة مع المصفوفات.

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

ثم أغرب مع سلاسل

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

تزداد الأمور سوءا:

متى يساوي لا يساوي؟

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

دعني أقول ذلك مرة أخرى:

(A == B) && (B == C) // true
(A == C) // **FALSE**

وهذه هي فقط الأشياء المجنونة التي تحصل عليها مع الأوليات.

إنه مستوى جديد تمامًا من الجنون عندما تستخدم == مع الكائنات.

في هذه المرحلة ربما تتساءل ...

لماذا يحدث هذا؟

حسنا ، لأنه على عكس "يساوي الثلاثي" ( === ) الذي يتحقق فقط إذا كانت قيمتين هي نفسها.

== يفعل مجموعة كاملة من الأشياء الأخرى .

لديها معالجة خاصة للوظائف ، معالجة خاصة للقيم الخالية ، غير محددة ، السلاسل ، سمها ما شئت.

انها تحصل على أحمق جدا.

في الواقع ، إذا حاولت كتابة وظيفة تقوم بعمل ما == هل سيبدو شيء مثل هذا:

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

فماذا يعني هذا؟

يعني == معقدة.

لأن الأمر معقد ، من الصعب معرفة ما سيحدث عند استخدامه.

مما يعني أنه يمكن أن ينتهي بك الأمر مع البق.

لذلك فإن المعنى من القصة هو ...

اجعل حياتك أقل تعقيدًا.

استخدم === بدلا من == .

النهاية.


Answer #3

=== يحدد المشغل القيم وكذلك أنواع المتغيرات للمساواة.

== يفحص المشغل فقط قيمة المتغيرات للمساواة.


Answer #4

باستخدام == المشغل ( المساواة )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

باستخدام عامل التشغيل === ( الهوية )

true === 1; //false
"2" === 2;  //false

وذلك لأن عامل المساواة == يقوم بكتابة القسر ، وهذا يعني أن المترجم يحاول ضمنيًا تحويل القيم قبل المقارنة.

من ناحية أخرى ، فإن عامل تشغيل الهوية === لا يفعل نوع الإكراه ، وبالتالي لا يقوم بتحويل القيم عند المقارنة.


Answer #5

يتصرف مشغل الهوية ( === ) بشكل مشابه لمعاملة المساواة ( == ) باستثناء عدم إجراء تحويل النوع ، ويجب أن تكون الأنواع هي نفسها التي يجب اعتبارها متساوية.

المرجع: برنامج جافا سكريبت التعليمي: مشغّلو مقارنة

سيقارن العامل == للمساواة بعد القيام بأي تحويلات من النوع الضروري . لن يقوم عامل التشغيل === بالتحويل ، لذا إذا لم تكن قيمتان من النوع نفسه === فسيتم إرجاع false . كلاهما سريع على قدم المساواة.

لنقتبس من نصوص جافا سكريبت الرائعة لدوغلاس كروكفورد : The Good Parts ،

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

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

إن الافتقار إلى العبور أمر ينذر بالخطر. نصيحتي هي عدم استخدام التوائم الشريرة أبداً. بدلا من ذلك ، استخدم دائما === و !== . كل المقارنات التي تظهر للتو تنتج false مع عامل التشغيل === .

تحديث:

تم طرح نقطة جيدة بواسطة @Casebash في التعليقات وإجابةPhillipe Laybaert المتعلقة بأنواع المراجع. لأنواع المراجع == و === تتصرف باستمرار مع بعضها البعض (ما عدا في حالة خاصة).

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

الحالة الخاصة هي عندما تقارن حرفيًا بكائن يتم تقييمه بنفس valueOf الحرفية ، نظرًا valueOf toString أو valueOf . على سبيل المثال ، ضع في الاعتبار مقارنة سلسلة حرفية مع كائن سلسلة تم إنشاؤه بواسطة مُنشئ String .

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

هنا يقوم عامل التشغيل == بفحص قيم الكائنين والعودة true ، ولكن === يرى أنهما ليسا من نفس النوع وأنهما false . أيهما الصحيح؟ هذا يعتمد على ما تحاول مقارنته. نصيحتي هي تجاوز السؤال تماما ومجرد عدم استخدام منشئ String لإنشاء كائنات سلسلة.

مرجع
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


Answer #6

مثال بسيط هو

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

Answer #7

من غير المحتمل أن يكون هناك أي فرق في الأداء بين العمليتين في الاستخدام الخاص بك. لا يوجد نوع التحويل الذي يجب القيام به لأن كلا المعلمتين من نفس النوع بالفعل. سيكون لكل من العمليات مقارنة نوع متبوعة بمقارنة القيمة.



Answer #9

مقارنة المساواة:

المشغل أو العامل ==

يعود صحيح ، عندما يكون كلا المعاملات متساوية. يتم تحويل المعاملات إلى نفس النوع قبل مقارنة.

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

المساواة ونوع المقارنة:

المشغل أو العامل ===

إرجاع true إذا كانت كل المعاملات متساوية ومن النوع نفسه. عادةً ما يكون أفضل وأكثر أمانًا إذا قارنت هذه الطريقة ، لأنه لا يوجد تحويلات من نوع وراء الكواليس.

>>> 1 === '1'
false
>>> 1 === 1
true

Answer #10

يسمى عامل التشغيل === مشغل مقارنة صارم ، ولكنه يختلف عن المشغل == .

دعونا نأخذ 2 فارين أ و ب.

بالنسبة لـ "a == b" لتقييمه إلى true ، يجب أن يكون b هو نفس القيمة .

في حالة "a === b" يجب أن يكون a و b نفس القيمة وأيضًا نفس النوع ليتم تقييمه إلى true.

خذ المثال التالي

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

باختصار باستخدام معامل == قد يتم تقييمه إلى true في الحالات التي لا تريد فيها استخدام ذلك فإن عامل التشغيل === سيكون أكثر أمانًا.

في سيناريو الاستخدام بنسبة 90٪ ، لا يهم أيًا منهما تستخدمه ، ولكن من السهل معرفة الفرق عندما تحصل على سلوك غير متوقع يومًا ما.


Answer #11

تكمن المشكلة في أنك قد تواجه مشكلة بسهولة لأن جافا سكريبت بها الكثير من التحويلات الضمنية التي تعني ...

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

والتي سرعان ما تصبح مشكلة. يمكن أخذ أفضل عينة من لماذا التحويل الضمني هو "الشر" من هذه التعليمة البرمجية في MFC / C ++ التي سيتم تجميع بالفعل بسبب تحويل ضمني من CString إلى HANDLE وهو نوع typedef مؤشر ...

CString x;
delete x;

التي من الواضح خلال وقت التشغيل أشياء غير محددة للغاية ...

جوجل للتحويلات الضمنية في C ++ و STL للحصول على بعض الحجج ضدها ...


Answer #12

ببساطة

==يعني المقارنة بين المعاملات مع type conversion

و

===يعني المقارنة بين المعاملات دون type conversion

تحويل النوع في javaScript يعني أن javaScript يقوم تلقائيًا بتحويل أي أنواع بيانات أخرى إلى أنواع بيانات السلسلة.

فمثلا:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

Answer #13

دعني أضيف هذا المحامي:

إذا كنت في شك ، اقرأ specification !

ECMA-262 هي مواصفات لغة البرمجة النصية التي تعتبر JavaScript بها اللهجة. وبالطبع من الناحية العملية ، من المهم أن تتصرف أكثر المتصفحات أهمية من تعريف مقصور على فئة معينة لكيفية التعامل مع شيء ما. ولكن من المفيد أن نفهم لماذا New String ("a")! == "a" .

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

البحث في ملف PDF ل === يقودني إلى صفحة 56 من المواصفات: 11.9.4. مشغل متساوٍ متساوٍ (===) ، وبعد الخوض من خلال المواصفات التي أجدها:

11.9.6 خوارزمية المقارنة الصارمة للمساواة
المقارنة x === y ، حيث x و y هي قيم ، تنتج صحيحة أو خاطئة . يتم إجراء مثل هذه المقارنة على النحو التالي:
1. إذا كان النوع (x) مختلفًا عن Type (y) ، فأرجع false .
2. إذا كان النوع (x) غير معرّف ، فأرجع true .
3. إذا كان Type (x) هو Null ، فأرجع true .
4. إذا كان النوع (س) ليس رقم ، انتقل إلى الخطوة 11.
5. إذا كانت x هي NaN ، قم بإرجاع false .
6. إذا كان y هو NaN ، فأرجع كاذباً .
7. إذا كانت x هي نفس قيمة الرقم y ، قم بإرجاع true .
8. إذا كانت x هي +0 و y هي −0 ، فعليك بإرجاع true .
9. إذا كانت قيمة x هي −0 و y هي +0 ، قم بإرجاع true .
10. العودة كاذبة .
11. إذا كانت Type (x) هي String ، فحينئذٍ ترجع true إذا كان x و y هما بالضبط نفس تسلسل الأحرف (نفس الطول والحروف نفسها في المواضع المقابلة) ؛ خلاف ذلك ، تعود كاذبة .
12. إذا كان النوع (x) منطقيًا ، فأرجع true إذا كان x و y كلاهما صحيحين أو كاذبين . خلاف ذلك ، تعود كاذبة .
13. قم بإرجاع true إذا كان x و y يشيران إلى نفس الكائن أو إذا كانا يشيران إلى كائنات مرتبطة ببعضها (انظر 13.1.2). خلاف ذلك ، تعود كاذبة .

المثير للاهتمام هو الخطوة 11. نعم ، تعامل السلاسل على أنها أنواع قيم. ولكن هذا لا يفسر لماذا New String ("a")! == "a" . هل لدينا متصفح غير متوافق مع ECMA-262؟

ليس بهذه السرعة!

دعونا تحقق من أنواع المعاملات. جرب بنفسك عن طريق التفافها في typeof () . أجد أن String ("a") الجديد عبارة عن كائن ، ويتم استخدام الخطوة 1: إرجاع false إذا كانت الأنواع مختلفة.

إذا كنت تتساءل عن سبب عدم إرجاع السلسلة الجديدة ("a") إلى سلسلة ، فما رأيك في بعض التمرينات في قراءة المواصفات؟ إستمتع!

كتب Aidiakapi هذا في تعليق أدناه:

من المواصفات

11.2.2 المشغل الجديد :

إذا كان النوع (منشئ) غير كائن ، فقم برمي استثناء TypeError.

بكلمات أخرى ، إذا لم تكن السلسلة من نوع الكائن ، فلا يمكن استخدامها مع المشغل الجديد.

جديدًا دائمًا ما يعرض كائنًا ، حتى بالنسبة لمُنشئات السلسلة أيضًا. و للأسف! يتم فقدان دلالات القيم للسلاسل (راجع الخطوة 11).

وهذا يعني أخيرا: سلسلة جديدة ("أ")! == "أ" .


Answer #14

لقد اختبرت هذا في Firefox باستخدام Firebug باستخدام كود مثل:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

و

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

نتائجي (تم اختبارها خمس مرات لكل ومتوسط):

==: 115.2
===: 114.4

لذا ، أود أن أقول إن الاختلاف الضئيل (أكثر من 100000 تكرار ، تذكر) لا يكاد يذكر. الأداء ليس سبباً للقيام به === . اكتب الأمان (جيد ، آمن كما ستحصل على JavaScript) ، وجودة الكود هي.


Answer #15

JavaScript === vs == .

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

Answer #16

مخطط تدفق تنفيذ جافا سكريبت للمساواة / المقارنة "==="

مخطط تدفق تنفيذ جافا سكريبت لعدم المساواة التامة / المقارنة '=='


Answer #17

كقاعدة عامة ، سأستخدم بشكل عام ===بدلاً من ==( !==وبدلاً من !=).

تم توضيح الأسباب في الإجابات أعلاه ، كما أن دوغلاس كروكفورد واضحًا جدًا ( JavaScript: The Good Parts ).

ومع ذلك ، هناك استثناء واحد : == nullهي طريقة فعالة للتحقق من "القيمة فارغة أو غير محددة":

if( value == null ){
    // value is either null or undefined
}

على سبيل المثال مسج 1.9.1 يستخدم هذا النمط 43 مرات، و مدقق بناء الجملة JSHint حتى يوفر eqnullخيار مريح لهذا السبب.

من دليل نمط jQuery :

يجب استخدام شيكات المساواة الشريفة (===) لصالح ==. الاستثناء الوحيد هو عند التحقق من وجود غير معرفة والقيمة خالية عن طريق خالية.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

Answer #18

في الإجابات هنا ، لم أقرأ أي شيء عن الوسائل المتساوية . سيقول البعض أن === تعني المساواة من نفس النوع ، لكن هذا ليس صحيحًا حقًا. يعني في الواقع أن كلا المعاملات تشير إلى نفس الكائن ، أو في حالة أنواع القيم ، لها نفس القيمة .

لذا ، لنأخذ الرمز التالي:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

الشيء نفسه هنا:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

او حتى:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

هذا السلوك ليس دائما واضح. هناك قصة أكثر من كونها متساوية وكونها من نفس النوع.

القاعدة هي:

لأنواع القيم (الأرقام):
إرجاع a === b true إذا كان a و b لهما نفس القيمة وهما من نفس النوع

لأنواع المراجع:
a === b تُرجع true إذا كان a و b يشيران إلى نفس الكائن بالضبط

للسلسلة:
a === b تُرجع true إذا كان a و b كلاهما يحتويان على الأحرف نفسها

السلاسل: الحالة الخاصة ...

السلاسل ليست أنواع قيم ، ولكنها في Javascript تتصرف مثل أنواع القيم ، لذلك ستكون "متساوية" عندما تكون الأحرف في السلسلة متماثلة وعندما تكون من نفس الطول (كما هو موضح في القاعدة الثالثة)

الآن يصبح من المثير للاهتمام:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

لكن ماذا عن هذا؟

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

اعتقدت أن السلاسل تتصرف مثل أنواع القيم؟ حسنًا ، يعتمد الأمر على من تسأل ... في هذه الحالة ، لا يكون a و b من النوع نفسه. a من نوع Object ، في حين أن b من نوع string . فقط تذكر أن إنشاء كائن سلسلة باستخدام مُنشئ String ينشئ شيئًا من نوع Object الذي يتصرف كسلسلة في معظم الأوقات .


Answer #19

في PHP وجافا سكريبت ، هو مشغل صارم للمساواة. مما يعني أنه سيقارن بين النوع والقيم.


Answer #20

نعم فعلا! مهم.

===يقوم المشغل في javascript بالتحقق من القيمة بالإضافة إلى الكتابة حيث يقوم ==المشغل بالتحقق من القيمة فقط (يقوم بتحويل النوع إذا لزم الأمر) .

يمكنك اختبارها بسهولة. الصق الكود التالي في ملف HTML وافتحه في المتصفح

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

سوف تحصل على ' false ' في حالة تأهب. الآن تعديل onPageLoad()طريقة ل alert(x == 5);ستحصل صحيح .


Answer #21

ويتحقق مما إذا كانت الجوانب متساوية في النوع وكذلك القيمة .

مثال:

'1' === 1 // will return "false" because `string` is not a `number`

المثال الشائع:

0 == ''  // will be "true", but it's very common to want this check to be "false"

مثال شائع آخر:

null == undefined // returns "true", but in most cases a distinction is necessary

Answer #22

* المشغلون === مقابل == *

1 == true    =>    true
true == true    =>    true
1 === true    =>    false
true === true    =>    true

Answer #23

إنه اختبار فحص صارم.

إنه أمر جيد خاصة إذا كنت تتحقق من 0 إلى false و null.

على سبيل المثال ، إذا كان لديك:

$a = 0;

ثم:

$a==0; 
$a==NULL;
$a==false;

كل عوائد صحيح وربما لا تريد هذا. لنفترض أن لديك دالة يمكنها إرجاع فهرس 0 من صفيف أو خطأ عند الفشل. إذا قمت بالتحقق من "==" false ، يمكنك الحصول على نتيجة مربكة.

لذلك مع نفس الشيء على النحو الوارد أعلاه ، ولكن اختبار صارم:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false




identity-operator