The data type

  • Original value type “Value type/Base data type”
    • The Number of digital
    • Boolean Boolean
    • String String
    • Null Null object pointer
    • Undefined Undefined
    • Symbol unique value??
    • Bigint number???
  • Object type “Reference data type”
    • Standard common object Object
    • Standard special objects Array, RegExp, Date, Math, Error…
    • Nonstandard special objects Number, String, Boolean……
    • Can call/execute object “function” function

What are the common data type detection methods?

1. Typeof operator

Grammar:

var str = typeof [value]
Copy the code

Used to check the data type of a given variable

Return value: a string containing the corresponding data type.

Always return one of the following strings:

  • ‘undefined’ => Undefined value
  • ‘Boolean’ => Boolean value
  • ‘number’ = > value
  • ‘string’ => string
  • “Symbol” => unique value
  • ‘bignit’ = > large Numbers
  • ‘function’ => Function is an object, not a data type
  • ‘object’ => The detected value is an object or NULL

Principle (underlying mechanism) : Values of all data types are stored as “binary” “64-bit” in the underlying computer

Typeof checks data types according to stored “binary values”, such as:

  • Objects starting with 000 =>
  • The value starting with 1 is an integer
  • A floating point number starting with 010
  • A string starting with 100 =>
  • If the value starts with 110 => A Boolean value
  • 000000… . => null

If the first three digits of a value are 000, they are considered objects. On this basis, the object is checked to see if the [[Call]] method is implemented internally

  • If implemented, it is considered a function and returns “function”.
  • None, return “object”.

Advantages:

  • Because TypeOF detects data types as stored “binary values,” performance is better when using Typeof to detect data types.
  • When detecting values of primitive value types (except null), the results are accurate.

Disadvantages (Limitations) :

  • Typeof null returns ‘object’
  • When using Typeof to detect values of object types, objects cannot be subdivided. All object type values return “object” except function objects.
  • Using Typeof to detect an undeclared variable does not generate an error, but returns “undefined”.

2. Instanceof operator

We usually don’t care if a value is an object, but rather what kind of object it is.

Grammar:

var result = value instanceof Ctor
// Ctor => constructor
Copy the code

Function: Checks whether an instance belongs to this class. You can compensate for typeof by subdividing object types.

The return value:

  • True => Instances belong to this class
  • False => Instances do not belong to this class

Ctor constructor () : Symbol. HasInstance () : Symbol. HasInstance () : Symbol.

  • If it exists, it is checked based on this method Ctor[Symbol.hasInstance](value)
  • If the property method is not available, get the prototype chain of value (until foundObject.prototypeSo far)
    • ifCtor.prototypeAppearing on its prototype chain proves that value is an instance of Ctor,
    • The other way around is not…
  • In the new version of the browser, inFunction.prototypeThere is a property method onSymbol.hasInstance, so as long as the function “whether ordinary function, or constructor”, haveSymbol.hasInstanceThis method…

Disadvantages (Limitations) :

  • withinstanceofTo test the data type, is a temporary “make up number”, so the answer is for reference only.
  • withinstanceofDetecting any reference values and Object constructors returns true. Because all reference values are instances of Object.
  • withinstanceofDetecting the original value always returns false because the original value is not an object.

Case 1:

let n = [];
console.log(n instanceof Array); //true
console.log(n instanceof RegExp); // false
console.log(n instanceof Object); //true All referenced values are instances of Object.
Copy the code

Example 2:

Custom constructors that borrow prototype objects from other constructors may result in inaccurate test results.

The constructor Fn in the following code borrows array.prototype.

function Fn() {}
Fn.prototype = Array.prototype;
let f = new Fn;
console.log(f instanceof Array); // true The test result is incorrect.
Copy the code

Example 3:

Override of Symbol. HasInstance property of built-in class is invalid


Array[Symbol.hasInstance] = function () {
    return 100;
};
let n = [];
console.log(n instanceof Array);  //=> true
Copy the code

Example 4:

Custom constructor that can specify the symbol.hasinstance property. It could lead to inaccurate test results.

class Fn {
    static[Symbol.hasInstance](val) {
        return false; }}let f = new Fn; // f is an instance of the constructor Fn
console.log(f instanceof Fn); //false
console.log(Fn[Symbol.hasInstance](f)); //false
Copy the code

3. constructor

Grammar:

varResult = instance object. Constructor;Copy the code

Gets the constructor of the instance.

Return value: Constructor to which the instance object belongs (heap address)

Principle (underlying mechanism) :

Most functions have a Prototype attribute, followed by a constructor attribute.

By default, the constructor attribute refers back to the constructor associated with it.

Disadvantages (Limitations) :

  • withconstructorTo detect the data type is also a temporary pull to make up the number, so also unreliable.
  • constructorThe direction of a property can be arbitrarily changed.
  • nullDuring a visit toconstructorProperty, an error is reported.

Case 1:

Constructor can be used to test whether an Object is a standard plain Object “pure Object” or a direct instance of Object.

N is a direct instance of Array, not RegExp and Object.

let n = [];
console.log(n.constructor === Array); // true
console.log(n.constructor === RegExp); // false
console.log(n.constructor === Object);  // false
Copy the code

Example 2:

When accessing the constructor property with raw values, the default is “boxing”.

Boxing means that the original value is converted to an instance of the object type created by its constructor, so that the original value can call methods on the stereotype of the class to which it belongs.

let n = 1;
console.log(n.constructor === Number);
// true
// Change the default value of 1 to an instance of the object type new Number(1)
Copy the code

Example 3:

Modified the constructor attribute to point to incorrect detection results

let n = [];
Array.prototype.constructor = 'AAA'; //=>false
console.log(n.constructor === Array);
Copy the code

Example 4:

Null returns an error when accessing the constructor property

(null).constructor
// Uncaught TypeError: Cannot read property 'constructor' of null
Copy the code

4. Object.prototype.toString.call([value])

Grammar:

Copy the code

Most prototypes have toString methods that convert to strings…

But the Object. The prototype. ToString is not used to convert a string, but detection data types

Return value: “[object?] “

[value][Symbol. ToStringTag]

  • If there is this attribute, what is the attribute value @X? The result of the final detection is “[object @X]”.
    • If it does not have this property, it is processed according to the built-in class to which it belongs

Advantages:

This method works really well… There are few bugs, except that it’s a little more difficult to write

Case 1:

Calls to the Object. The prototype. The toString (), the method of this is who, who is testing data types

/ / 1.
let obj = {
    name: 'xiaoming'
}
console.log(obj.toString());
//=> "[object Object]" -> Object.prototype.toString


// 2. Use call() to change the this direction of method execution
Object.prototype.toString.call([10.20])
// =>"[object Array]"

// 3. In actual development, this will be done to simplify the code
let obj = {},
    toString = obj.toString; // => Object.prototype.toString
console.log(toString.call(1)); // => "[object Number]"
Copy the code

Example 2:

Number. The prototype. ToString the instance of an array into a string

  • Numbers. ToString () converts numbers to strings
  • Numbers. ToString (radix) A string that converts numbers to radix values
// Do not specify radix, default is decimal number
console.log((2).toString());
/ / "2"

// The radix is 2, and the radix is 2
console.log((2).toString(2));
10 "/ /"
Copy the code

Example 3:

console.log([10.20.30].toString());
/ / - > 10, 30 "" - > Array. The prototype. ToString

Copy the code

Example 4:

Adds the attribute symbol.toStringTag to the prototype object for the custom constructor

class Fn {
    constructor() {
        this.name = 'zhufeng';
        this[Symbol.toStringTag] = 'Fn'; }}let f = new Fn;
console.log(toString.call(f)); / / = > "[object Fn]"
Copy the code

Encapsulate several functions for data detection

1. Check whether it is a function

var isFunction = function isFunction(obj) {
    return typeof obj === 'function' && typeofobj.nodeType ! = ="number" &&  typeofobj.item ! = ="function"
}
Copy the code

Typeof obj === ‘function’ typeof obj === ‘function’ That’s to deal with two compatibility issues:

  1. typeof document.createElement("object")==="function"

  2. typeof document.getElementsByTagName("div")==="function"

    There is an '<object>' element in HTML. Add Flash files to HTML using the <object> element. Some browsers recognize <object> elements as functions, so we need to exclude <object> elements. So how can you rule it out? In JavaScript, all DOM Node types inherit from Node types. This means that every DOM Node has access to properties and methods on Node.prototype. Node.prototype has a nodeType property that indicates the type of the Node. Node types are represented by 12 numeric constants defined on the Node type. So no matter what typeof node, the value type returned is 'number', i.e. 'typeof obj.nodetype! = = "number" `. Through ` document. The getElementsByTagName () ` get is a ` HTMLCollection ` element collection. HTMLCollection provides methods and attributes for selecting elements from the collection. There is a static method item() that returns a specific node based on the given index (starting from 0).Copy the code

2. Check whether the object is window

const isWindow = function isWindow(obj) {
        returnobj ! =null && obj === obj.window
    }
Copy the code

3. Methods for detecting data types (Octadathlon)


let toString = {}.toString;
// {}.toString => Object.prototype.toString

const toType = function toType(obj) {
        let reg = /^\[object ([0-9a-zA-Z]+)\]$/;
        // null & undefined
        if (obj == null) return obj + ' ';
        // Other types
        return typeof obj === 'object' || typeof obj === 'function' ? reg.exec(toString.call(obj))[1].toLowerCase() : typeof obj ;
    }

console.log(toType(0)); // 'number'
console.log(toType($/ / ^));  // 'regexp'
Copy the code