元生JS魂の質問――これらのJSは本当に分かりますか?


最近ES 6を読んでいます.(初めて会社に来たせいか、興奮と忙しいことによる無力感があります.でも、「深入浅出ES 6」をしっかり読んでいます.確かにいい本です.)中には時々「はっとする」という感じがあります.
まずJSデータタイプを言います.
元のデータタイプと参照データタイプ
元のデータタイプ(6種類)
  • book
  • null
  • undefined
  • number
  • string
  • smbol
  • 参照データの種類:
  • オブジェクトobject(object、Aray、RegExp、Date、Math…を含む)
  • 関数Function
  • ここの「null」は対象ですか?console.log(typeof null);、アウトプットします.しかし、これはJSの存在が長いBugで、対象ではありません.しかし、JSの初使用の32ビットシステムは、性能を考慮して下位格納変数のタイプ情報を使用し、000先頭は対象であるが、nullは全0であるため、objectと判定される.
    タイプを正しく判断できますか?
    オリジナルタイプについては、nullを除いて正確に判断できることを知っています.ただし、参照データの種類は、関数以外はすべてobjectです.このようにtypeofを採用するのはちょっと不適当です.私たちはinstance of-プロトタイプチェーンベースのクエリを思い付きました.
    var str='hello!';
    str instanceof String   // false
    
    const Person=function(){}
    const p1=new Person()
    p1 instanceof Person   // true
    
    もちろん、基本データの種類も判断できます.
    class PrimitiveNum{
    	static [Symbol.hasInstance](x){
    		return typeof x==='number'
    	}
    }
    console.log(111 instanceof PrimitiveNum)   // true
    
    実は、私たちはSymbolを通じて元のinstance ofをtypeofと定義し直しました.これはカスタムinstance ofの行動の一つです.
    刺激的な遊びをして、
    手動でinstance ofを実現
    プロトタイプチェーンによる上向き検索を思い出しました.
    function myInstanceof(left,right){
    	//          false
    	if(typeof left !== 'object' || left === null) return false;
    	//  Object              
    	let proto=Object.getPrototypeOf(left);
    	while(true){
    		if(proto==null) return false;   //        null
    		if(proto==right.prototype) return true;
    		proto=Object.getPrototypeOf(proto);   //     ,    “    ”,     
    	}
    }
    
    テストします
    console.log(myInstanceof("111",String));   // false
    console.log(myInstanceof(new String("111"),String));   // true
    
    興味深いことに、「深入浅出ES 6」にもこの例がある.
    function makeRequest(url,timeout,callback){
    	timeout=(typeof timeout !== "undefined") ? timeout : 2000;
    	callback=(typeof callback !== "undefined") ? callback : function(){};
    	//    
    }
    
    運用:instance of左の操作数は1つのクラスで、右の操作数は対象を識別するクラスで、左側のオブジェクトが右のクラスの例であれば、trueに戻ります.したがって、基本タイプはtypeofで判断します.残りはinstance ofで判断します.
    Object.isと==
    ES 6の新規方法として、Object.is()とObject.assign()はESに「簡潔で便利な風」を巻き起こしました.私達はObject.is()の方法を改めて説明します.
    「深入浅出ES 6」では、JavaScriptで2つの値を比較したい場合、等しい演算子(=)や完全な演算子(===)を使用することに慣れているかもしれません.多くの開発者は後者が好きで、比較時に強制的なタイプ変換をトリガする行為を避けることができます.
    しかし、すべての演算子は必ずしも正確ではないです.+0と-0はJavaScriptエンジンで2つの完全に異なるエンティティとして表されていますが、完全な演算子は1つのカテゴリーに分類されます.NaN==NaNの戻り値はtrueであるべきであるが、JavaScriptにおいてもisNaN()を用いて表現する必要がある.
    ES 6は、Object.is()法を導入して、全等式演算子の不正確な演算を補います.
    console.log(+0 == -0);   // true
    console.log(+0 === -0);   // false
    console.log(Object.is(+0,-0));   // false
    
    console.log(NaN == NaN);   // false
    console.log(NaN === NaN);   // false
    console.log(Object.is(NaN,NaN));   // true
    
    console.log(5 == "5");   // true
    console.log(5 === "5");   // false
    console.log(Object.is(5,"5"));   // false
    
    0.1+0.2!==0.3
    疑いなくてもいいです.確かにそうです.内部原理は何ですか?私達のコンピュータの情報はすべて二進法に変換して保存しています.0.1の二進法は無限循環小数点を表しています.JSは浮動小数点の基準を採用しています.この無限循環の二進法を切り取ります.これによって精度が失われ、0.1はもう0.1ではないということになります.02は0.200…002になりましたので、加算した数は0.3より多いです.なぜ0.3+0.4=0.5ですか?コンピュータはデータを切り取り、合理的な値を得ることができる.実際的には、0.3切り取り後の値に0.4切り取りを加えた値は、ちょうど0.5切り取り後の値となります.どうしてコンソールのsoline.log(0.1)で、まだ0.1に等しいですか?入力内容を変換するときは、バイナリを10進数に変換し、10進数を文字列に変換します.この変換の過程で近似値を取ります.だから印刷されたのは近似値です.