ホームページ  >  記事  >  ウェブフロントエンド  >  フロントエンドで書かれたテストと JS の暗黙的な変換の問題の落とし穴

フロントエンドで書かれたテストと JS の暗黙的な変換の問題の落とし穴

hzc
hzc転載
2020-06-17 10:00:321974ブラウズ

筆記試験問題を作成するとき、

"1" + 2
obj + 1
[] == ![] 
[null] == false

=== や ==

=== などの暗黙的な変換を伴う問題に遭遇することがよくあります。厳密演算子と呼ばれます。オブジェクト型は、同じアドレスまたは同じ元の型 (数値、文字列、ブール値) 値を指します。== は等価演算子と呼ばれます。異なる型は変換され比較されます。 。未定義と null は同じです。オブジェクト タイプは参照のままです。 == 演算子は、元の値とそのラップされたオブジェクトを等しいものとして扱いますが、=== 演算子はそれらを等しくないものとして扱います。 すべて obj.a==null (obj.a=== null || obj.a ===unknown と同等)。

等価演算子はJSで暗黙的な変換を引き起こす罠であり、インタビューの質問にもよく出てきますが、実際の開発では無用な問題を避けるために厳密な演算子を使用する必要があります。しかし、それでも理解する必要があります。

JS の暗黙的な変換を理解したい場合は、まず 3 つの知識ポイントから始める必要があります。

プリミティブ型

プリミティブ型 (基本型、基本データ型、プリミティブ データ型) は、オブジェクトでもメソッドでもないデータです。 JavaScript には、文字列、数値、bigint、ブール、null、未定義、シンボル (ECMAScript 2016 の新機能) の 7 つの型があります。

偽値 (仮想値)

偽値 (仮想値) は、ブール値コンテキストで偽とみなされる値です。偽値は 7 個だけですJavaScriptで。

  1. false false キーワード
  2. 0 値ゼロ
  3. 0n BigInt がブール値として使用される場合、値としての規則に従います。0n は偽の値です。
  4. 空の文字列 (文字列の長さはゼロ)。JavaScript の文字列は、二重引用符 ""、一重引用符 ''、またはテンプレート リテラル `` で定義できます。
  5. null null - 欠落した値
  6. 未定義 未定義 - 元の値
  7. NaN NaN - 数値以外の値

特に、これを除く7 つのオブジェクトはすべて、新しい数値や新しいブール値などの true 値を持ちます。

let b = new Boolean(false);i
f(b){
//会执行到这里。
}

4 つの主要な変換ルール

  • toString ルール: 他の型の値を文字列型に変換する操作

    • null =>「null」
    • 未定義 =>「未定義」
    • true =>「true」 false=>「false」
    • 10 = > "10" "1e21"=>"1e 21"
    • [1,2,3] =>「1,2,3」
    • オブジェクト object=> 「[Object Object]」は実際には toString メソッドを呼び出しています
  • ##ToPrimitive ルール : オブジェクト型配列をプリミティブ型に変換する操作

      オブジェクト型をプリミティブ型に変換する必要がある場合、最初にオブジェクトの valueOf メソッドが検索されます。valueOf メソッドがプリミティブ型の値を返す場合、ToPrimitive の結果は次のようになります。 value
    • valueOf が存在しない場合、または valueOf メソッドがプリミティブ型ではない値を返した場合、オブジェクトの toString メソッドの呼び出しを試みます。つまり、オブジェクトの ToString ルールに従い、その後、 ToPrimitive
    • Date の結果としての toString の戻り値は、最初に toString 、次に ValueOf
    • toString と ValueOf の後で元の型が取得できない場合、等しいかどうかを判断するときにスローされます。加算と減算
    • Uncaught TypeError: オブジェクトをプリミティブ値に変換できません
  • ##ToNumber Rule
  • null => 0

    未定義 => NaN
    • "123" =>123 "12ssd"=>NaN ""=>0
    • false => ; 0 true=>1
    • Array, objectToPrimitive
    ToBoolean ルール
  • 7 つjs の false 値 (仮想値) は false、その他は true

    • 暗黙の変換
  • #上記の知識ポイントを理解した上で、 JS の暗黙的な変換を一気に廃止することができます。
  • == 的过程(优先换成数字、字符串)
  1. 首先看==前后有没有NaN,有的话都是返回false。NaN不等于任何值,包括其本身
  2. 布尔值会转成数字类型,true转成1,false转成0
  3. 数字和字符串比较,字符串会转成数字
  4. undefined和null除了和undefined或null相等,和其他相比都是false
  5. 数字或者字符串和对象相比,对象使用ToPrimitive规则转换。
  6. 当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。
  • +的过程(优先换成字符串、数字)
  1. 如果至少有一个操作数是对象,它会被转换成原始值(字符串,数字或布尔);
  2. 转换之后,如果至少有一个操作数是字符串类型,第二个操作数会被转换成字符串,并且会执行连接。
  3. 在其他的情况下,两个操作数都会转换成数字并执行算数加法运算。
  • -的过程(转换成数字) 这个就很简单了,全部用ToNumber规则转换成数字

检测学习成果

我们根据以上所学看几个笔试题。如果你都知道结果,就不用看我的废解释了。

[] == [] 
[] == ![] 
[null] == false

第一个,==左右都是对象,比较引用地址,这个两个不同的实例,肯定不相等啊。 第二个,!的优先级高于==,所以先 [] 是真值,求非当让是false了,转成数字0,==左是对象右是数字,对象使用ToPrimitive规则转换成"",再用ToNumber规则就转成0了,判断为相等。 第三个,[null]ToPrimitive再ToNumber规则就转成0,false也转成0。

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

var obj1 = {
    i:1,
    toString:function() {
        return "1";
    },
    valueOf:function() {
        return 1;
    }
};
var obj2 = {
    i:1,
    toString:function() {
        return "2";
    }
};
var obj3 = {
    i:1,
    valueOf:function() {
        return 3;
    }
};
var obj = {
    i:1,
};
var objE = {
    i:1,
    valueOf:function() {
        return [];
    },
    toString:function() {
        return {};
    }
};


a+b  
a + obj  
a + objE 

a+obj1  
a+obj2  
a+obj3  

b+obj1  
b+obj2  
b+obj3  

a==obj2  
a==obj1

这道题比较简单你只要熟练掌握我上面说的那几个知识点可以了。下面直接写出结果啦。

a + b    //"13"
a + obj  //"1[object Object]"
a + objE //Uncaught TypeError: Cannot convert object to primitive value

a+obj1  //2
a+obj2  //"12"
a+obj3  // 4

b+obj1  //"31"
b+obj2  //"32"
b+obj3  //“33”

a==obj2  //false
a==obj1  //true

最后提一个比较奇葩的题目。

定义一个变量a,使得下面的表达式结果为true

  a == 1 && a == 2 && a == 3

这里我简单提示下,a要是一个对象,重写valueOf方法,让它每次隐式转换的时候,调用时i++。

フロントエンドで書かれたテストと JS の暗黙的な変換の問題の落とし穴

valueOf()在Object上默认返回的是对象不是原始类型,它会再调用toString。所以只要重写toString也可以。

如果还是没有思路,你们可以去看下这道题的文章原文从一道面试题说起—js隐式转换踩坑合集。

推荐教程:《JS教程

以上がフロントエンドで書かれたテストと JS の暗黙的な変換の問題の落とし穴の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。