Who hasn’t been victimized by an object type error in a front-end project?
The typeof operator
Obtain the typeof the operand through the typeof operator:
typeof undefined; // undefined
typeof []; // object
typeof '123'; // string
Copy the code
There are two things to remember about the Typeof operator. The first is when the operand is null.
typeof null; // object
Copy the code
Point two: This works well when the operands are Primitive, but a determination of the specific type of the object is often not the result we need.
Null, Undefined, String, Number, Boolean, and Symbol.
typeof '123'; // string
typeof new String('123'); // object
Copy the code
When we first started learning javascript, we often heard that “everything in JS is an object”. In fact, the Primitive Value does not contain the Primitive Value.
The instanceof operator
The instanceof operator is used to check whether the constructor stereotype is in the stereotype chain of the object.
const s = new String('123');
s instanceof String; // true
s instanceof Object; // true
Copy the code
Now let’s do something:
s.__proto__ = Object.prototype;
s instanceof String; // false
s instanceof Object; // true
Copy the code
Using the instanceof operator, we can determine the value of a custom object:
function Animal (name) {
this.name = name
}
const fizz = new Animal('fizz');
fizz instanceof Animal // true
Copy the code
The constructor property
In fact, we can also achieve the effect of type judgment using the constructor attribute:
fizz.constructor === Animal // true
Copy the code
In real life, however, the constructor property can be modified at will, and it’s easy to overlook constructor’s correct orientation in stereotype inheritance:
function Rabbit (name) {
Animal.call(this, name)
}
Rabbit.prototype = Object.create(Animal.prototype);
// You need to manually set the correct orientation for constructor
Rabbit.prototype.constructor = Rabbit;
const rabbit = new Rabbit('🐰');
rabbit.constructor === Rabbit // true
Copy the code
As a matter of good programming practice, we should keep the constructor property pointed correctly.
The toString method
The toString method solves almost all of the built-in object types:
function type (obj) {
return Reflect.apply(Object.prototype.toString, obj, []).replace(/^\[object\s(\w+)\]$/.'$1').toLowerCase()
}
type(new String('123')) // string
Copy the code
However, this method is still invalid for custom constructors.
Built-in Symbol interface
ES6 exposes some built-in apis through Symbol:
Animal.prototype[Symbol.toStringTag] = 'Animal';
type(rabbit) // animal
Copy the code
Now, we can satisfy all of our requirements with toString, but there is no shortage of superficial programmers:
const o = {
get [Symbol.toStringTag] () {
return 'Array'
}
}
type(o) // array
Copy the code
The exception also exposes Symbol. HasInstance for the instanceof operator, which will not be repeated here.
The pit of those years
Here’s a simple example:
function test (decimal) {
if (type(decimal) === 'number') {
return decimal.toFixed(2)}else if (type(decimal) === 'string') {
return parseFloat(decimal).toFixed(2)}else {
return '0.00'
}
}
test(28.39843) / / 28.40
test('323.2321321') / / 323.23
Copy the code
Anyone who has used the toFixed() method knows that it is a method on number.prototype, and that there are all sorts of problems if you pass in something other than a Number type.
Of course we are in an era of a boom in front-end tools, with many tools for static type checking emerging:
- Produced by the Flow. Js Facebook
- TypeScript Microsoft ‘
For those of you who like this article, please follow my subscription account for more content.