Judgment method of data type and summary of conversion method

image.pngText content:

  • Introduces several commonly used data type judgment methods , and writes a general judgment method by hand
  • Common methods and rules for mandatory type conversion and implicit type conversion , as well as common interview questions

Data type detection

Method 1: typeof

  • typeof is often used to judge the basic data type, and there will be bugs in judging the reference type
  • typeof null will output object, but this is just a long-standing bug in JS, it does not mean that null is a reference data type, and null itself is not an object
  • The reference data type cannot be judged. If you use typeof to judge, except function will be judged correctly, the rest are 'object'.
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'

Method 2: instanceof

  • instanceof is often used to determine the reference data type
  • instanceof operator is used to detect  prototype whether the properties of the constructor function appear on the prototype chain of an instance object.
let Car = function() {}
let benz = new Car()
benz instanceof Car // true

let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false

handwritten instaneof

  1. First use typeof to judge the basic data type, if yes, return false directly
  2. Get the prototype object of the parameter, and loop down to find and judge until the same prototype object is found
function myInstanceof(left, right) {
  // 这里先用typeof来判断基础数据类型,如果是,直接返回false
  if(typeof left !== 'object' || left === null) return false;
  // getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
  let proto = Object.getPrototypeOf(left);
  while(true) {                  //循环往下寻找,直到找到相同的原型对象
    if(proto === null) return false;
    if(proto === right.prototype) return true;//找到相同原型对象,返回true
    proto = Object.getPrototypeof(proto);
    }
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number));    // true
console.log(myInstanceof(123, Number));                // false
  • instanceofCan accurately judge complex reference data types, but cannot correctly judge basic data types;
  • And typeofthere are also disadvantages. Although it can judge the basic data type (except null), it functioncannot judge other reference data types except the type.

Method 3: Object.prototype.toString

  • toString() is the prototype method of Object. Calling this method can uniformly return a string in the format of “[object Xxx]”, where Xxx is the type of the object.
  • For the Object object, directly call toString() to return [object Object]; for other objects, you need to call
Object.prototype.toString({})       // "[object Object]"
Object.prototype.toString.call({})  // 同上结果,加上call也ok
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)   //"[object Window]"

Optimal solution: handwriting a global general judgment method

principle:

  1. First judge whether it is the basic type, if so, return the type directly
  2. If it is an object type, use Object.prototype.toStringthe judgment method to perform regular matching
function getType(obj){
  let type  = typeof obj;
  if (type !== "object") {    // 先进行typeof判断,如果是基础数据类型,直接返回
    return type;
  }
  // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');  // 注意正则中间有个空格
}
/* 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?思考下 */
getType([])     // "Array" typeof []是object,因此toString返回
getType('123')  // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null)   // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined)   // "undefined" typeof 直接返回
getType()            // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g)      //"RegExp" toString返回

type conversion

Let's start with a small question and experience it

'123' == 123   // false or true?    
'' == null    // false or true?     
'' == 0        // false or true?   
[] == 0        // false or true?   
[] == ''       // false or true?    
[] == ![]      // false or true?    
null == undefined //  false or true?  
Number(null)     // 返回什么?         
Number('')      // 返回什么?          
parseInt('');    // 返回什么?         
{}+10           // 返回什么?          
let obj = {
    [Symbol.toPrimitive]() {
        return 200;
    },
    valueOf() {
        return 300;
    },
    toString() {
        return 'Hello';
    }
}
console.log(obj + 200); // 这里打印出来是多少?  

The answer is at the bottom, see how much you can get right

cast

Mandatory type conversion methods include Number(), parseInt(), parseFloat(), toString(), String(),Boolean()

implicit type conversion

All operations through logical operators &&、 ||、 !, operators +、-、*、/, relational operators >、 <、 <= 、>=, equality operators, ==or if/whileconditions are considered implicit type conversions

==+Several implicit type conversion rules for and

==Implicit type conversion rules for

  1. If the types are the same, no type conversion is required;
  2. If one of the operation values ​​is null or undefined, then the other operator must be null or undefined to return true, otherwise both return false;
  3. If one of them is of Symbol type, return false;
  4. If the two operation values ​​are string and number types, then the string will be converted to a number;
  5. If an operation value is boolean, then convert to number;
  6. If one operation value is object and the other is string, number or symbol, the object will be converted to the original type and then judged (call the valueOf/toString method of object to convert).
null == undefined       // true  规则2
null == 0               // false 规则2
'' == null              // false 规则2
'' == 0                 // true  规则4 字符串转隐式转换成Number之后再对比
'123' == 123            // true  规则4 字符串转隐式转换成Number之后再对比
0 == false              // true  e规则 布尔型隐式转换成Number之后再对比
1 == true               // true  e规则 布尔型隐式转换成Number之后再对比
var a = {
  value: 0,
  valueOf: function() {
    this.value++;
    return this.value;
  }
};
// 注意这里a又可以等于1、2、3
console.log(a == 1 && a == 2 && a ==3);  //true f规则 Object隐式转换
// 注:但是执行过3遍之后,再重新执行a==3或之前的数字就是false,因为value已经加上去了,这里需要注意一下

+Implicit type conversion rules for

The '+' operator can be used not only for adding numbers, but also for string concatenation. Only when both sides of the '+' sign are numbers, the addition operation is performed; if both sides are strings, they are directly concatenated without implicit type conversion.

In addition to the more general cases described above, there are some special rules, as follows.

  1. If one of them is a string and the other is undefined, null or Boolean, call the toString() method for string splicing; if it is a pure object, array, regular expression, etc., the conversion method of the default calling object will have priority (The next lecture will be specifically introduced), and then stitching.
  2. If one of them is a number and the other is undefined, null, Boolean or number, it will be converted into a number for addition. For the object, refer to the previous rule.
  3. If one of them is a string and the other is a number, splicing is performed according to the string rules.
下面还是结合代码来理解上述规则,如下所示。
  1 + 2        // 3  常规情况
  '1' + '2'    // '12' 常规情况
  // 下面看一下特殊情况
  '1' + undefined   // "1undefined" 规则1,undefined转换字符串
  '1' + null        // "1null" 规则1,null转换字符串
  '1' + true        // "1true" 规则1,true转换字符串
  '1' + 1n          // '11' 比较特殊字符串和BigInt相加,BigInt转换为字符串
  1 + undefined     // NaN  规则2,undefined转换数字相加NaN
  1 + null          // 1    规则2,null转换为0
  1 + true          // 2    规则2,true转换为1,二者相加为2
  1 + 1n            // 错误  不能把BigInt和Number类型直接混合相加
  '1' + 3           // '13' 规则3,字符串拼接

Answer

'123' == 123   // false or true?    true
'' == null    // false or true?     false
'' == 0        // false or true?    true
[] == 0        // false or true?    true
[] == ''       // false or true?    true
[] == ![]      // false or true?    true
null == undefined //  false or true?  true
Number(null)     // 返回什么?         0
Number('')      // 返回什么?          0
parseInt('');    // 返回什么?         NaN
{}+10           // 返回什么?          10
let obj = {
    [Symbol.toPrimitive]() {
        return 200;
    },
    valueOf() {
        return 300;
    },
    toString() {
        return 'Hello';
    }
}
console.log(obj + 200); // 这里打印出来是多少?  400

This article is published by OpenWrite, a multi-post platform for blogging !

Guess you like

Origin blog.csdn.net/buruyang/article/details/124577448