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.