Delicious value: 🌟🌟🌟🌟🌟
Taste: Shrimp balls with mustard
In order to align with Teacher Yi, let’s have a brief review first.
JavaScript data types include primitive types and object types:
- Primitive types: Null, Undefined, Number, String, Boolean, Symbol, BigInt
- Object type: Object
We are used to referring to objects as reference types, and of course there are many special reference types, such as Function, Array, RegExp, Math, Date, Error, Set, Map, various stereotyped arrays TypedArray, etc.
The primitive type value is stored in the stack, and the object type value is stored in the heap, keeping the reference address of the object in the stack, and when JavaScript accesses the data, it accesses it through the reference in the stack.
In JavaScript, an assignment of a primitive type copies the value of a variable, while an assignment of an object (reference) type copies the reference address.
Let’s practice our skills with two more common interview questions
let a = {
name: 'Front Canteen'.age: 2
}
let b = a
console.log(a.name)
b.name = 'Baby Oba'
console.log(a.name)
console.log(b.name)
// Front-end canteen
/ / child Obama
/ / child Obama
Copy the code
The first question is So Easy that you can answer it with your eyes closed.
let a = {
name: 'Front Canteen'.age: 2
}
const expand = function(b) {
b.age = 18
b = {
name: 'Baby Oba'.age: 25
}
return b
}
let c = expand(a)
console.log(c.age)
console.log(a.age)
console.log(a)
/ / 25
/ / 18
// {name: "Front-End dining hall ", age: 18}
Copy the code
Some students may get this question wrong, so let’s analyze it together:
Expand is passing the memory address of the object in the heap. You can change the age property of object A by calling b.age = 18.
{name: “child obar “, age: 25}; age: 25}
Next, let’s give a warm applause to welcome Mr. Yi.
I’ll ask you some questions, and you can always drink.
Do you know of any JavaScript methods for detecting data types?
- typeof
- instanceof
- constructor
- Object.prototype.toString.call()
So how does typeof work?
1.typeof
typeof 'a' // 'string'
typeof 1 // 'number'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol('a') // 'symbol'
typeof 1n // 'bigint'
typeof null // 'object'
typeof function() {} // 'function'
typeof [] // 'object'
typeof {} // 'object'
typeof /a/ // 'object'
typeof new Date(a)// 'object'
typeof new Error(a)// 'object'
typeof new Map(a)// 'object'
typeof new Set(a)// 'object'
Copy the code
Two conclusions:
- Typeof determines primitive types other than NULL.
- Typeof can only determine the typeof object Function, other types of object.
Why are typeof null values object?
Typeof returns object when detecting null, a Bug in the original JavaScript language that has been retained for compatibility with older code.
If you want to learn more, please click the link below.
- link
Tips
NaN has to be mentioned here, because we all know that he plays a lot.
typeof NaN // number
Copy the code
F**k NaN!
Do you know which types instanceof can identify?
2.instanceof
Checks whether the constructor’s Prototype property appears on the prototype chain of an instance object.
That is, a instanceof B is used to judge whether a is an instanceof B, that is, whether there is a constructor of B on the prototype chain of a.
console.log(1 instanceof Number) // false
console.log(new Number(1) instanceof Number) // true
const arr = []
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true
const Fn = function() {
this.name = 'Constructor'
}
Fn.prototype = Object.create(Array.prototype)
let a = new Fn()
console.log(a instanceof Array) // true
Copy the code
Two conclusions:
instanceof
Object (reference) types can be accurately determined, but primitive types cannot be accurately detected.- This method is not safe because we can modify the orientation of the prototype at will to lead to inaccurate detection results.
If I just want to check primitive types with Instanceof, can you meet my needs?
Ok, satisfied.
Although Instanceof cannot detect primitive types, there is a way to use it to detect primitive types.
Symbol.hasinstance allows us to customize the behavior of instanceof.
class PrimitiveNumber {
static [Symbol.hasInstance] = x= > typeof x === 'number';
}
123 instanceof PrimitiveNumber; // true
class PrimitiveString {
static [Symbol.hasInstance] = x= > typeof x === 'string';
}
'abc' instanceof PrimitiveString; // true
class PrimitiveBoolean {
static [Symbol.hasInstance] = x= > typeof x === 'boolean';
}
false instanceof PrimitiveBoolean; // true
class PrimitiveSymbol {
static [Symbol.hasInstance] = x= > typeof x === 'symbol';
}
Symbol.iterator instanceof PrimitiveSymbol; // true
class PrimitiveNull {
static [Symbol.hasInstance] = x= > x === null;
}
null instanceof PrimitiveNull; // true
class PrimitiveUndefined {
static [Symbol.hasInstance] = x= > x === undefined;
}
undefined instanceof PrimitiveUndefined; // true
Copy the code
The code source is linked below.
- Is there a way to use instanceof for raw JavaScript values?
Since you know so much about Instanceof, can you hand write one for me on the spot?
Handwritten instanceof
const myInstanceof = function(left, right) {
if (typeofleft ! = ='object' || left === null) return false
let proto = Reflect.getPrototypeOf(left)
while (true) {
if (proto === null) return false
if (proto === right.prototype) return true
proto = Reflect.getPrototypeOf(proto)
}
}
const arr = []
console.log(myInstanceof(arr, Array)) // true
console.log(myInstanceof(arr, Object)) // true
console.log(myInstanceof(arr, RegExp)) // false
Copy the code
To understand how Instanceof works, you need to understand prototype chains. For those of you who are not familiar with JavaScript prototype chains, check out the link below.
- JavaScript goes from prototype to prototype chain
- How to answer the JavaScript prototype chain question in an interview
B: How about constructor?
3.constructor
For numeric immediates, using constructor directly returns an error from literal parsing of floating-point numbers, rather than processing “.” as the access operator.
In JS, floating point decimal places are nullable, so 1. And 1.0 are parsed to the same floating point number.
// A parenthesis operator is needed to convert a value to an object
(1).constructor ƒ Number() {[native code]}
/ / or
1..constructor ƒ Number() {[native code]}
const a = 'Front Canteen'
console.log(a.constructor) ƒ String() {[native code]}
console.log(a.constructor === String) // true
const b = 5
console.log(b.constructor) ƒ Number() {[native code]}
console.log(b.constructor === Number) // true
const c = true
console.log(c.constructor) ƒ Boolean() {[native code]}
console.log(c.constructor === Boolean) // true
const d = []
console.log(d.constructor) ƒ Array() {[native code]}
console.log(d.constructor === Array) // true
const e = {}
console.log(e.constructor) ƒ Object() {[native code]}
console.log(e.constructor === Object) // true
const f = () = > 1
console.log(f.constructor) ƒ Function() {[model]}
console.log(f.constructor === Function) // true
const g = Symbol('1')
console.log(g.constructor) ƒ Symbol()
console.log(g.constructor === Symbol) // true
const h = new Date(a)console.log(h.constructor) ƒ Date() {[native code]}
console.log(h.constructor === Date) // true
const i = 11n
console.log(i.constructor) ƒ BigInt() {[native code]}
console.log(i.constructor === BigInt) // true
const j = /a/
console.log(j.constructor) ƒ RegExp() {[native code]}
console.log(j.constructor === RegExp) // true
String.prototype.constructor = 'aaa'
console.log(a.constructor === String) // false
const k = null
console.log(k.constructor) // Cannot read property 'constructor' of null
const l = undefined
console.log(l.constructor) // Cannot read property 'constructor' of undefined
Copy the code
Two conclusions:
- Except for null and undefined,
constructor
Primitive and object (reference) types are correctly detected. - Because we can modify at will
constructor
Results in inaccurate detection results, so this method is not safe.
Left of the Object. The prototype. ToString, it perfect?
4.Object.prototype.toString
The toString() method returns a string representing the object, and we can change its this to point to the value to be tested to return information about the current tested value.
Object.prototype.toString({}) // '[object Object]'
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call('a') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call(Symbol('a')) // '[object Symbol]'
Object.prototype.toString.call(11n) // '[object BigInt]'
Object.prototype.toString.call(/a/) // '[object RegExp]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call([0.1.2]) // '[object Array]'
Object.prototype.toString.call(function() {}) // '[object Function]'
Object.prototype.toString.call(new Error()) // '[object Error]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Copy the code
Can you encapsulate a general method for detecting data types?
Encapsulate a common way to detect data types
Be case sensitive when encapsulating methods.
There are many kinds of schemes, here simply provide two ideas.
const getType = function(obj) {
let type = typeof obj
if(type ! = ='object') {
return type
}
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/.'$1').toLowerCase()
}
getType({}) // object
getType('a') // string
getType(1) // number
getType(true) // boolean
getType(null) // null
getType(undefined) // undefined
getType(Symbol('a')) // symbol
getType(11n) // bigint
getType(/a/) // regexp
getType(new Date()) // date
getType([0.1.2]) // array
getType(function() {}) // function
getType(new Error()) // error
getType(new Map()) // map
getType(new Set()) // set
Copy the code
Of course, you can do this by changing your position.
Object.prototype.toString.call('1').slice(8, -1).toLowerCase()
// 'string'
Copy the code
At this point, it’s almost a perfect answer.
If you think you missed something, feel free to add it in the comments section.
The last question from Mr. Yi is:
Do you like JavaScript?
❤️ Love triple punch
1. If you think the food and drinks in the canteen are ok with you, please give me a thumbs-up. Your thumbs-up is my biggest motivation.
2. Pay attention to the front canteen of the public account and eat every meal!
3. Like, comment, forward === urge more!