This is the 16th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Typeof grammar

When we want to determine whether an object is a primitive data type or a reference data type, typeof can be used to accurately determine.

// Numbers
typeof 37= = ='number';
typeof 3.14= = ='number';
typeof(42) = = ='number';
typeof Math.LN2 === 'number';
typeof Infinity= = ='number';
typeof NaN= = ='number'; // Despite being "Not-A-Number"
typeof Number('1') = = ='number';      // Number tries to parse things into numbers
typeof Number('shoe') = = ='number';   // including values that cannot be type coerced to a number

typeof 42n= = ='bigint';

// Strings
typeof ' '= = ='string';
typeof 'bla'= = ='string';
typeof `template literal`= = ='string';
typeof '1'= = ='string'; // note that a number within a string is still typeof string
typeof (typeof 1) = = ='string'; // typeof always returns a string
typeof String(1) = = ='string'; // String converts anything into a string, safer than toString

// Booleans
typeof true= = ='boolean';
typeof false= = ='boolean';
typeof Boolean(1) = = ='boolean'; // Boolean() will convert values based on if they're truthy or falsy
typeof!!!!! (1) = = ='boolean'; // two calls of the ! (logical NOT) operator are equivalent to Boolean()

// Symbols
typeof Symbol() = = ='symbol'
typeof Symbol('foo') = = ='symbol'
typeof Symbol.iterator === 'symbol'

// Undefined
typeof undefined= = ='undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined';

// Objects
typeof {a: 1} = = ='object';

// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1.2.4= = ='object';

typeof new Date() = = ='object';
typeof /regex/ === 'object'; // See Regular expressions section for historical results

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) = = ='object';
typeof new Number(1) = = ='object';
typeof new String('abc') = = ='object';

// Functions
typeof function() = = = {}'function';
typeof class C = = = {}'function';
typeof Math.sin === 'function';
Copy the code

But be warned:

When we typeof null === ‘object’; We get object, which is an unexpected result. So we can use a judgment statement to prepare a pair of how do we determine whether a data type is a primitive data type or a reference data type? Answer:

How do YOU determine whether a data type is a base data type or a reference data type?
const plainValues = ['number'.'string'.'boolean'.'bigint'.'symbol'.'undefined'.'null']

function isPlainValue(value) {
  if (value === null) {
    return true
  }
  return plainValues.includes(typeof value)
}
const flag = isPlainValue()
console.log(flag)
Copy the code
How do I determine if this variable is a function
function c() {}
const d = () = > {}
class Person {}
function* gen() {}
async function asf() {}
const fn = new Function(a)console.log(typeof c)
console.log(typeof d)
console.log(typeof Person)
console.log(typeof gen)
console.log(typeof asf)
console.log(typeof fn)
Copy the code

All of the above prints are functions.

instanceof

P1 instanceof Person

The instanceof keyword is a prototype that checks whether p1 objects have a Person constructor on their prototype chain. It is used to determine custom objects. Such as determining whether the instantiated object belongs to a constructor.

Implement an Instanceof

function instance(left,right){
      left=left.__proto__
      right=right.prototype
      while(true) {if(left==null)
                return false;
           if(left===right)
                return true;
           left=left.__proto__
      }
}
Copy the code

When we create an Object using const obj = object.create (null). Obj instanceof Object is false, so we usually use instanceof to determine custom instantiated objects.

How do I determine if a data is an array

Array.isArray(value)

Object.prototype.toString

Object. The prototype. The toString () method returns an Object character string form.

EcmaScript defined types using Object. The prototype. ToString can accurate judgment.

Object.prototype.toString.call(123) // [object Number]
Object.prototype.toString.call('str') // [object String]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(123n) // [object BigInt]
Object.prototype.toString.call(Symbol()) // [object Symbol]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call({}) // [object Object]
Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call(Math) // [object Math]
Object.prototype.toString.call(JSON) // [object JSON]
Object.prototype.toString.call(new Function()) // [object Function]
Object.prototype.toString.call(new Date()) // [object Date]
Object.prototype.toString.call(new RegExp()) // [object RegExp]
Object.prototype.toString.call(new Error()) // [object Error]
Copy the code

In the previous section we talked about how to determine if a variable is a function

So how do we determine what type of function a function is?

What type of function is a function

So what if we want to determine whether a function is labeled async or generator? You can also use the Object. The prototype. ToString.

Object.prototype.toString.call(async function () {}) // [object AsyncFunction]
Object.prototype.toString.call(function* () {}) // [object GeneratorFunction]
Object.prototype.toString.call(async function* () {}) // [object AsyncGeneratorFunction]
Copy the code

How do I tell the difference between normal functions and arrow functions

const arrow_fn = () = > {}
function fn() {}
console.log(arrow_fn.prototype) // undefined
console.log(fn.prototype) / / {constructor: ƒ}
Copy the code

But this approach is also unreliable.

Because the object by defining a Symbol to change the object. The prototype, the toString (). ToStringTag attribute, resulting in unexpected results.

const myDate = new Date(a);Object.prototype.toString.call(myDate);     // [object Date]

myDate[Symbol.toStringTag] = 'myDate';
Object.prototype.toString.call(myDate);     // [object myDate]

Date.prototype[Symbol.toStringTag] = 'prototype polluted';
Object.prototype.toString.call(new Date()); // [object prototype polluted]
Copy the code

So, to be on the safe side, we first check whether obj[symbol.tostringTag] exists before we judge an object. Then in the Object. The prototype. The toString (). Of course, if the object is under our control, we don’t have to judge. And this method is more accurate.

Conclusion: we all can use to determine type of the Object. The prototype. The toString judge, when using a custom constructor instantiation Object, we use the instanceof to determine the type of the Object.