it-swarm.asia

هل يمكن (أ = 1 && أ == 2 && أ == 3) تقييم أي وقت مضى إلى صحيح؟

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

هل يمكن على الإطلاق تقييم (a== 1 && a ==2 && a==3) إلى true في JavaScript؟

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

2376
Dimpu Aravind Buddha

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

const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

سبب هذا يرجع إلى استخدام عامل المساواة فضفاضة. عند استخدام مساواة فضفاضة ، إذا كان أحد المعاملات من نوع مختلف عن الآخر ، فسيحاول المحرك تحويل واحد إلى الآخر. في حالة وجود كائن على اليسار ورقم على اليمين ، سيحاول تحويل الكائن إلى رقم عن طريق الاتصال أولاً بـ valueOf إذا كان قابلاً للاستدعاء ، وإذا تعذر ذلك ، فسوف يتصل بـ toString. لقد استخدمت toString في هذه الحالة لمجرد أنه ما يتبادر إلى الذهن ، فإن valueOf سيكون له معنى أكبر. إذا قمت بدلاً من ذلك بإرجاع سلسلة من toString ، فسيحاول المحرك حينئذٍ تحويل السلسلة إلى رقم يمنحنا النتيجة النهائية نفسها ، على الرغم من وجود مسار أطول قليلاً.

3226
Kevin B

لم أستطع المقاومة - الإجابات الأخرى صحيحة بلا شك ، لكن لا يمكنك فعلاً تجاوز الشفرة التالية:

var aᅠ = 1;
var a = 2;
var ᅠa = 3;
if(aᅠ==1 && a== 2 &&ᅠa==3) {
    console.log("Why hello there!")
}

لاحظ التباعد الغريب في عبارة if (التي نسختها من سؤالك). إنه Hangul بعرض نصف (هذا كوري لأولئك الذين ليسوا مألوفين) وهو حرف مساحة Unicode لا يتم تفسيره بواسطة برنامج ECMA كحرف مساحة - وهذا يعني أنه حرف صالح لمعرف. لذلك هناك ثلاثة متغيرات مختلفة تمامًا ، أحدها مع الهانغول بعد الأخر ، والآخر به من قبل والأخير بآخر. استبدال المسافة بـ _ لقابلية القراءة ، سيبدو نفس الرمز كما يلي:

var a_ = 1;
var a = 2;
var _a = 3;
if(a_==1 && a== 2 &&_a==3) {
    console.log("Why hello there!")
}

تحقق من التحقق من صحة على Mathias 'متغير اسم المدقق . إذا تم تضمين هذا التباعد الغريب فعليًا في سؤالهم ، فأنا متأكد من أنه تلميح لهذا النوع من الإجابة.

لا تفعل هذا. بشكل جاد.

تحرير: لقد لاحظت أنه (على الرغم من عدم السماح ببدء تشغيل متغير) ، فإن نجار العرض الصفري و و- الصفر الصفري - غير نجار الأحرف مسموح بها أيضًا في أسماء متغير - انظر التعتيم جافا سكريبت مع الأحرف ذات العرض الصفري - إيجابيات وسلبيات؟ .

هذا سيبدو كما يلي:

var a= 1;
var a‍= 2; //one zero-width character
var a‍‍= 3; //two zero-width characters (or you can use the other one)
if(a==1&&a‍==2&&a‍‍==3) {
    console.log("Why hello there!")
}
2003
Jeff

IT IS ممكن!

var i = 0;

with({
  get a() {
    return ++i;
  }
}) {
  if (a == 1 && a == 2 && a == 3)
    console.log("wohoo");
}

هذا يستخدم getter داخل عبارة with للسماح لـ a بالتقييم إلى ثلاث قيم مختلفة.

... هذا لا يزال لا يعني أن هذا ينبغي أن تستخدم في رمز حقيقي ...

والأسوأ من ذلك ، ستعمل هذه الخدعة أيضًا مع استخدام ===.

  var i = 0;

  with({
    get a() {
      return ++i;
    }
  }) {
    if (a !== a)
      console.log("yep, this is printed.");
  }
601
Jonas Wilms

مثال بدون حروف أو valueOf:

a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);

يعمل هذا لأن == تستدعي toString الذي يستدعي .join للصفائف.

حل آخر ، باستخدام Symbol.toPrimitive وهو مكافئ ES6 لـ toString/valueOf:

let i = 0;
let a = { [Symbol.toPrimitive]: () => ++i };

console.log(a == 1 && a == 2 && a == 3);
476
georg

إذا تم سؤالك عما إذا كان من الممكن (لا يجب) ، فيمكنه أن يطلب من "a" إرجاع رقم عشوائي. سيكون صحيحًا إذا كان يولد 1 و 2 و 3 بالتتابع.

with({
  get a() {
    return Math.floor(Math.random()*4);
  }
}){
  for(var i=0;i<1000;i++){
    if (a == 1 && a == 2 && a == 3){
      console.log("after " + (i+1) + " trials, it becomes true finally!!!");
      break;
    }
  }
}
262
ocomfd

عندما لا تستطيع فعل أي شيء دون تعبيرات منتظمة:

var a = {
  r: /\d/g, 
  valueOf: function(){
    return this.r.exec(123)[0]
  }
}

if (a == 1 && a == 2 && a == 3) {
    console.log("!")
}

إنه يعمل بسبب custom valueOf الأسلوب الذي يتم استدعاؤه عند مقارنة الكائن مع البدائي (مثل Number). الخدعة الرئيسية هي أن a.valueOf تُرجع قيمة جديدة في كل مرة لأنها تستدعي exec في تعبير منتظم بعلامة g ، والتي تسبب تحديث lastIndex من هذا التعبير العادي في كل مرة يتم العثور على تطابق منتظم. لذلك في المرة الأولى this.r.lastIndex == 0 ، تتطابق مع 1 وتحديثات lastIndex: this.r.lastIndex == 1 ، لذلك في المرة القادمة سوف تتطابق regex مع 2 وهكذا.

205
Kos

ويمكن تحقيق ذلك باستخدام ما يلي في النطاق العالمي. من أجل nodejs ، استخدم global بدلاً من window في الكود أدناه.

var val = 0;
Object.defineProperty(window, 'a', {
  get: function() {
    return ++val;
  }
});
if (a == 1 && a == 2 && a == 3) {
  console.log('yay');
}

تفسد هذه الإجابة المتغيرات الضمنية التي يوفرها النطاق العام في سياق التنفيذ عن طريق تحديد getter لاسترداد المتغير.

188
jontro

هذا ممكن في حالة المتغير a الذي يتم الوصول إليه بواسطة ، قل 2 من عمال الويب من خلال SharedArrayBuffer بالإضافة إلى بعض النصوص الرئيسية. الاحتمال ضئيل ، لكن من المحتمل أنه عند ترجمة الشفرة إلى رمز الجهاز ، يقوم موظفو الويب بتحديث المتغير a في الوقت المناسب تمامًا بحيث تكون الشروط a==1 و a==2 و a==3 راضية.

يمكن أن يكون هذا مثالًا على حالة السباق في بيئة متعددة الخيوط يوفرها عمال الويب و SharedArrayBuffer في JavaScript.

هنا هو التنفيذ الأساسي لما ورد أعلاه:

main.js

// Main Thread

const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let's use 2 workers
const sab = new SharedArrayBuffer(1)

modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)

worker.js

let array

Object.defineProperty(self, 'a', {
  get() {
    return array[0]
  }
});

addEventListener('message', ({data}) => {
    array = new Uint8Array(data)
    let count = 0
    do {
        var res = a == 1 && a == 2 && a == 3
        ++count
    } while(res == false) // just for clarity. !res is fine
    console.log(`It happened after ${count} iterations`)
    console.log('You should\'ve never seen this')
})

modifier.js

addEventListener('message' , ({data}) => {
    setInterval( () => {
        new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
    })
})

على جهاز MacBook Air ، يحدث بعد حوالي 10 مليارات تكرار في المحاولة الأولى:

 enter image description here

محاولة ثانية:

 enter image description here

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

نصيحة: إذا استغرق الأمر وقتًا طويلاً في نظامك. حاول فقط a == 1 && a == 2 وتغيير Math.random()*3 إلى Math.random()*2. إضافة المزيد والمزيد إلى قائمة يسقط فرصة ضرب.

186
mehulmpt

هذا ممكن أيضًا باستخدام سلسلة من حروف الكتابة الذاتية:

(هذا مشابه لحل jontro ، ولكنه لا يتطلب متغير عداد.)

(() => {
    "use strict";
    Object.defineProperty(this, "a", {
        "get": () => {
            Object.defineProperty(this, "a", {
                "get": () => {
                    Object.defineProperty(this, "a", {
                        "get": () => {
                            return 3;
                        }
                    });
                    return 2;
                },
                configurable: true
            });
            return 1;
        },
        configurable: true
    });
    if (a == 1 && a == 2 && a == 3) {
        document.body.append("Yes, it’s possible.");
    }
})();
145
Patrick Dark

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

var a = 1;
var a = 2;
var а = 3;
if(a == 1 && a == 2 && а == 3) {
    console.log("Why hello there!")
}

قد تلاحظ تباينًا بسيطًا مع الثاني ، لكن الأول والثالث مماثلان للعين المجردة. جميع الشخصيات الثلاثة مميزة:

a - الحالة اللاتينية الصغيرة A
- عرض بالحروف اللاتينية بالأحرف الكاملة Full A
а - الحالة السيريلية الصغيرة A

المصطلح العام لذلك هو "الأشكال المتجانسة": أحرف يونيكود مختلفة تبدو متشابهة. عادة يصعب الحصول على ثلاثة لا يمكن تمييزها تمامًا ، لكن في بعض الحالات ، يمكنك الحظ. ستعمل A و Α و А و better بشكل أفضل (Latin-A و Greek Alpha و Cyrillic-A و و Cherokee-A على التوالي ؛ لسوء الحظ ، الأحرف الصغيرة اليونانية وشروكي تختلف كثيرا عن اللاتينية a: α ، ، وبالتالي لا تساعد في المقتطف أعلاه).

هناك فئة كاملة من هجمات Homoglyph هناك ، والأكثر شيوعًا في أسماء النطاقات المزيفة (على سبيل المثال. wikipediа.org (السيريلية) مقابل wikipedia.org (اللاتينية)) ، لكن يمكن أن تظهر في الكود أيضًا ؛ يشار إليها عادة بأنها مخادعة (كما هو مذكور في تعليق ، [مخادعة] الأسئلة أصبحت الآن خارج الموضوع على PPCG ، ولكنها اعتادت أن تكون نوعًا من التحدي حيث تظهر هذه الأنواع من الأشياء فوق). لقد استخدمت هذا الموقع للعثور على الأشكال المتجانسة المستخدمة في هذه الإجابة.

128
Draco18s

بدلاً من ذلك ، يمكنك استخدام فئة لها ومثيل للفحص.

function A() {
    var value = 0;
    this.valueOf = function () { return ++value; };
}

var a = new A;

if (a == 1 && a == 2 && a == 3) {
    console.log('bingo!');
}

تصحيح

باستخدام فئات ES6 سيبدو كهذا

class A {
  constructor() {
    this.value = 0;
    this.valueOf();
  }
  valueOf() {
    return this.value++;
  };
}

let a = new A;

if (a == 1 && a == 2 && a == 3) {
  console.log('bingo!');
}
124
Nina Scholz

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

»جافا سكريبت

if‌=()=>!0;
var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    document.write("<h1>Yes, it is possible!????</h1>")
}

الكود أعلاه هو نسخة قصيرة (بفضلForivin لملاحظاته في التعليقات) والرمز التالي أصلي:

var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    //console.log("Yes, it is possible!????")
    document.write("<h1>Yes, it is possible!????</h1>")
}

//--------------------------------------------

function if‌(){return true;}

إذا رأيت فقط الجانب العلوي من الكود وقمت بتشغيله ، فأنت تقول WOW ، كيف؟

لذلك أعتقد أنه يكفي قول {نعم ، من الممكن} لشخص قال لك: {لا شيء مستحيل}

الخدعة: استخدمت حرفًا مخفيًا بعد if لإنشاء دالة يشبه اسمها if. في JavaScript ، لا يمكننا تجاوز الكلمات الرئيسية ، لذلك اضطررت إلى استخدام هذه الطريقة. إنها if وهمية ، لكنها تعمل من أجلك في هذه الحالة!


» C #

كما كتبت إصدار C # (مع زيادة قيمة خاصية تكنيك):

static int _a;
public static int a => ++_a;

public static void Main()
{
    if(a==1 && a==2 && a==3)
    {
        Console.WriteLine("Yes, it is possible!????");
    }
}

Live Demo

98
RAM

جافا سكريبت

== 1+

في JavaScript ، لا توجد أعداد صحيحة ولكن Numbers فقط ، والتي يتم تنفيذها كأرقام فاصلة عائمة مزدوجة الدقة.

هذا يعني أنه إذا كان الرقم a كبيرًا بما يكفي ، فيمكن اعتباره مساوياً لثلاثة أعداد صحيحة متتالية:

a = 100000000000000000
if (a == a+1 && a == a+2 && a == a+3){
  console.log("Precision loss!");
}

صحيح ، هذا ليس بالضبط ما طلبه القائم بإجراء المقابلة (لا يعمل مع a=0) ، لكنه لا ينطوي على أي خدعة ذات وظائف خفية أو التحميل الزائد للمشغل.

لغات اخرى

كمرجع ، توجد حلول a==1 && a==2 && a==3 في Ruby و Python. مع تعديل بسيط ، من الممكن أيضًا في Java.

ياقوت

مع == مخصص:

class A
  def ==(o)
    true
  end
end

a = A.new

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

أو a متزايد:

def a
  @a ||= 0
  @a += 1
end

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

الثعبان

class A:
    def __eq__(self, who_cares):
        return True
a = A()

if a == 1 and a == 2 and a == 3:
    print("Don't do that!")

جافا

من الممكن تعديل ذاكرة التخزين المؤقت Java Integer :

package stackoverflow;

import Java.lang.reflect.Field;

public class IntegerMess
{
    public static void main(String[] args) throws Exception {
        Field valueField = Integer.class.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.setInt(1, valueField.getInt(42));
        valueField.setInt(2, valueField.getInt(42));
        valueField.setInt(3, valueField.getInt(42));
        valueField.setAccessible(false);

        Integer a = 42;

        if (a.equals(1) && a.equals(2) && a.equals(3)) {
            System.out.println("Bad idea.");
        }
    }
}
94
Eric Duminil

هذه نسخة مقلوبة من @ Jeff's answer * حيث يتم استخدام حرف مخفي (U + 115F أو U + 1160 أو U + 3164) لإنشاء متغيرات تبدو مثل 1 و 2 و 3.

var  a = 1;
var ᅠ1 = a;
var ᅠ2 = a;
var ᅠ3 = a;
console.log( a ==ᅠ1 && a ==ᅠ2 && a ==ᅠ3 );

* يمكن تبسيط هذه الإجابة عن طريق استخدام غير صفار عرض الصفر (U + 200C) ونجار عرض الصفر (U + 200D). يُسمح لكل من هذه الأحرف داخل المعرفات ولكن ليس في البداية:

var a = 1;
var a‌ = 2;
var a‍ = 3;
console.log(a == 1 && a‌ == 2 && a‍ == 3);

/****
var a = 1;
var a\u200c = 2;
var a\u200d = 3;
console.log(a == 1 && a\u200c == 2 && a\u200d == 3);
****/

الحيل الأخرى ممكنة باستخدام نفس الفكرة ، على سبيل المثال باستخدام محددات أشكال Unicode لإنشاء متغيرات تبدو متشابهة تمامًا (a︀ = 1; a︁ = 2; a︀ == 1 && a︁ == 2; // true).

79
Salman A

القاعدة رقم واحد من المقابلات ؛ لا تقل أبدا المستحيل.

لا حاجة للخداع شخصية خفية.

window.__defineGetter__( 'a', function(){
    if( typeof i !== 'number' ){
        // define i in the global namespace so that it's not lost after this function runs
        i = 0;
    }
    return ++i;
});

if( a == 1 && a == 2 && a == 3 ){
    alert( 'Oh dear, what have we done?' );
}
73
MonkeyZeus

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

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

أظن أن بعض المقابلات سوف يجرؤون على امتلاك ما هو واضح ليكون سؤالًا صعبًا للغاية ، لكنني لا أمانع المطورين الذين لديهم رأي ، خاصةً عندما يتمكنون من عمل نسخة احتياطية من التفكير المنطقي ويمكنهم دمج سؤالي في بيان هادف عن أنفسهم.

68
Frank W. Zammetti

إليك صيغة أخرى ، باستخدام صفيف لإظهار القيم التي تريدها.

const a = {
  n: [3,2,1],
  toString: function () {
    return a.n.pop();
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Yes');
}
41
Théophile

حسنا ، الاختراق آخر مع المولدات:

const value = function* () {
  let i = 0;
  while(true) yield ++i;
}();

Object.defineProperty(this, 'a', {
  get() {
    return value.next().value;
  }
});

if (a === 1 && a === 2 && a === 3) {
  console.log('yo!');
}
31
BaggersIO

في الواقع ، الإجابة على الجزء الأول من السؤال هي "نعم" في كل لغة برمجة. على سبيل المثال ، هذا في حالة C/C++:

#define a   (b++)
int b = 1;
if (a ==1 && a== 2 && a==3) {
    std::cout << "Yes, it's possible!" << std::endl;
} else {
    std::cout << "it's impossible!" << std::endl;
}
27
Gustavo Rodríguez

باستخدام الوكلاء :

var a = new Proxy({ i: 0 }, {
    get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name],
});
console.log(a == 1 && a == 2 && a == 3);

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

  1. نقوم بإنشاء كائن مستهدف ، { i: 0 } ، حيث الخاصية i هي عدادنا
  2. نقوم بإنشاء وكيل للعنصر الهدف ونعينه إلى a
  3. لكل مقارنة a == ، يتم إجبار نوع a إلى قيمة أولية
  4. ينتج عن هذا النوع من الإكراه استدعاء a[Symbol.toPrimitive]() داخليًا
  5. يعترض الوكيل الحصول على الدالة a[Symbol.toPrimitive] باستخدام "get getler"
  6. يتحقق "get get handler" من بروكسي من أن الخاصية التي حصلت عليها هي Symbol.toPrimitive ، وفي هذه الحالة تزيد وتعيد العداد من الكائن الهدف: ++target.i. إذا تم استرداد خاصية مختلفة ، فسنعود إلى إرجاع قيمة الخاصية الافتراضية ، target[name]

وبالتالي:

var a = ...; // a.valueOf == target.i == 0
a == 1 && // a == ++target.i == 1
a == 2 && // a == ++target.i == 2
a == 3    // a == ++target.i == 3

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

27
IceCreamYou

نفسه ، ولكن مختلف ، ولكن لا يزال نفسه (يمكن "اختباره" عدة مرات):

const a = { valueOf: () => this.n = (this.n || 0) % 3 + 1}
    
if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

بدأت فكرتي من كيفية عمل معادلة نوع كائن رقم.

26
Preda7or

إجابة ECMAScript 6 التي تستخدم الرموز:

const a = {value: 1};
a[Symbol.toPrimitive] = function() { return this.value++ };
console.log((a == 1 && a == 2 && a == 3));

نظرًا لاستخدام == ، من المفترض أن يقوم JavaScript بإكراه a إلى شيء قريب من المعامل الثاني (1، 2، 3 في هذه الحالة). ولكن قبل أن يحاول JavaScript تحديد الإكراه من تلقاء نفسه ، فإنه يحاول الاتصال Symbol.toPrimitive . إذا قدمت Symbol.toPrimitive ، فسيستخدم JavaScript القيمة التي تُرجعها وظيفتك. إذا لم يكن الأمر كذلك ، فستتصل JavaScript valueOf .

23
Omar Alshaker

أعتقد أن هذا هو الحد الأدنى من التعليمات البرمجية لتنفيذه:

i=0,a={valueOf:()=>++i}

if (a == 1 && a == 2 && a == 3) {
  console.log('Mind === Blown');
}

إنشاء كائن وهمية باستخدام valueOf الذي يزيد متغير عمومي i على كل مكالمة. 23 حرفا!

23
Gaafar

هذا واحد يستخدم identProperty مع آثار جانبية لطيفة تسبب متغير عمومي!

var _a = 1

Object.defineProperty(this, "a", {
  "get": () => {
    return _a++;
  },
  configurable: true
});

console.log(a)
console.log(a)
console.log(a)
12
Ben Aubin

من خلال تجاوز valueOf في إعلان فئة ، يمكن القيام بذلك:

class Thing {
    constructor() {
        this.value = 1;
    }

    valueOf() {
        return this.value++;
    }
}

const a = new Thing();

if(a == 1 && a == 2 && a == 3) {
    console.log(a);
}

ما يحدث هو أن valueOf يسمى في كل عامل مقارنة. في الأولى ، a تساوي 1 ، في الثانية ، a تساوي 2 ، وهكذا دواليك ، وهكذا ، لأنه يتم استدعاء valueOf ، يتم زيادة قيمة a.

وبالتالي ، فإن console.log ستطلق وتخرج (في طرفيه على أي حال) Thing: { value: 4} ، مما يشير إلى أن الشرطية كانت صحيحة.

0
Jonathan Kuhl