実装:(a == 1 && a == 2 && a == 3)=== true

序文

この質問には難しい解決策がありますが、この質問をしたときにインタビュアーが本当に調べたいのは、暗黙の変換の知識ポイントの理解と、データの乗っ取りを検討できるかどうかです。

トリッキーな解決策

let i=1;
with({
    
    
	get a() {
    
    
		return i++;
	}
}){
    
    
	if(a==1 && a==2 && a==3) {
    
    
		console.log('哈哈哈,成功了')}
}

暗黙の変換

jsで==2つの値を比較する場合、次の操作が実行されます:

  1. 2つの比較された値を同じタイプに変換します
  2. 変換後(方程式の片側または両側が変換される場合があります)、値の比較が実行されます

最終的な比較方法は===、等式演算子の比較方法と同等であり、等式演算子は可換法則を満たしています。
等式演算子は、次の図に示すように、さまざまなタイプの値を比較します。
ここに画像の説明を挿入
表から取得できる情報のポイントがいくつかあります(a == 1)a

  1. aはタイプStringであり、数値に変換可能です1('1' == 1 => true)
  2. aはタイプBooleanであり、数値に変換可能です1 (true == 1 => true)
  3. aのタイプはObject、変換メカニズムを通過した後、数値1に変換できます(以下を参照)。

オブジェクトのプリミティブ型への「変換メカニズム」
ルール1および2については、特別なことは何もありません。3を見てみましょう。
オブジェクトがプリミティブ型に変換されると、組み込み[ToPrimitive]関数が呼び出されます。ロジックはおおよそ次のとおりです。 :

  1. メソッドがある場合は、Symbol.toPrimitive最初にそれを呼び出してから戻ります。それ以外の場合は2に進みます。
  2. 呼び出しvalueOf、プリミティブ型に変換可能な場合は戻り、そうでない場合は3を実行します。
  3. を呼び出しtoString、プリミティブ型に変換可能な場合は戻り、それ以外の場合は4を実行します。
  4. どちらも元のタイプを返さない場合、エラーが報告されます。

解決:

const a = {
    
    
  i: 1,
  [Symbol.toPrimitive]() {
    
    
    return this.i++
  }
}
// 每次进行a == xxx时都会先经过Symbol.toPrimitive函数,自然也就可以实现a依次递增的效果
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('哈哈哈,成功了') 
}

もちろんvalueOftoString

const a = {
    
    
  i: 1,
  valueOf() {
    
    
    return this.i++
  }
}
// 每次进行a == xxx时都会先经过valueOf/toString函数,自然也就可以实现a依次递增的效果
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('哈哈哈,成功了') 
}

データハイジャック

Object.defineProperty、オブジェクトをハイジャックし、プロパティがwindow読み取られるたびに1ずつインクリメントします。a_a

Object.defineProperty(window, 'a', {
    
    
	get() {
    
    
		return _a++;
	}
})

あなたがそれを考えることができれば、definePropertyあなたは自然にそれを考えるでしょうproxy

let a =  new Proxy({
    
    i:1}, {
    
    
	get(target){
    
    
		console.log(target);
		return () => target.i++
	}
})

3つの方法、あなたはそれを学びましたか?

おすすめ

転載: blog.csdn.net/weixin_44761091/article/details/123891194