JavaScript basic types you may not understand!

Get into the habit of writing together! This is the 4th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

foreword

I will help you sort out and deeply learn the knowledge points of JavaScript data types from the concepts of data types, detection methods, and conversion methods .

data type concept

There are 8 data types in JavaScript as shown in the following figure:

image.png

The first 7 types are basic types, and the last type (Object) is a reference type, which is also what you need to pay attention to, because it is the most frequently used data type in daily work and the data type that requires the most attention to technical details.

There are also several reference types: Array - array object, RegExp - regular object, Date - date object, Math - mathematical function, Function - function object.

Storage differences between basic types and reference types:

  1. Basic type: stored in stack memory, when referenced or copied, a completely equal variable will be created;
  2. Reference type: Stored in heap memory, the address is stored, and multiple references point to the same address, which involves a concept of "sharing".

see a few cases

Topic 1

let a = {
  name: 'lee',
  age: 18
}
let b = a;
console.log(a.name);  // lee
b.name = 'son';
console.log(a.name);  // son
console.log(b.name);  // son
复制代码

It can be seen from the results that a and b use the same data source.

topic two

let a = {
  name: 'Julia',
  age: 20
}
function change(o) {
  o.age = 24;
  o = {
    name: 'Kath',
    age: 30
  }
  return o;
}
let b = change(a);
console.log(b.age);    // 30
console.log(a.age);    // 24
复制代码
  1. a is passed into change as a parameter. At this time, a and o share the same data, so the modification of o will affect a.
  2. When o is reassigned, there is no connection between o and a.

Data type detection

The first judgment method: typeof

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
复制代码
  1. The first 6 are basic data types;
  2. Although typeof null will output object , this is just a long-standing bug in JS. It does not mean that null is a reference data type, and null itself is not an object. Therefore, null returns a questionable result after typeof and cannot be used as a method for judging null. If you need to judge whether it is null in the if statement, just use '===null' to judge.
  3. If the reference data type is judged by typeof, except the function will judge as OK , the rest are all 'object', which cannot be judged.

The second judgment method: instanceof

let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
复制代码

Because all reference type data has prototypes, it can be judged from the prototype chain, instanceof source code:

function myInstanceof(left, right) {
  // 这里先用typeof来判断基础数据类型,如果是,直接返回false
  if(typeof left !== 'object' || left === null) return false;
  // getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
  let proto = Object.getPrototypeOf(left);
  while(true) {                  //循环往下寻找,直到找到相同的原型对象
    if(proto === null) return false;
    if(proto === right.prototype) return true;//找到相同原型对象,返回true
    proto = Object.getPrototypeof(proto);
  }
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number));    // true
console.log(myInstanceof(123, Number));                // false
复制代码

Advantages and disadvantages of the above two methods

  1. instanceof can accurately judge complex reference data types, but cannot correctly judge basic data types;
  2. And typeof also has drawbacks, although it can judge the basic data type (except null), but the reference data type, in addition to the function type, the other can not be judged.

Perfect method: Object.prototype.toString

Object.prototype.toString({})       // "[object Object]"
Object.prototype.toString.call({})  // 同上结果,加上call也ok
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)   //"[object Window]"
复制代码

Complete spelling:

function getType(obj){
  let type  = typeof obj;
  if (type !== "object") {    // 先进行typeof判断,如果是基础数据类型,直接返回
    return type;
  }
  // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');  // 注意正则中间有个空格
}
/* 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?思考下 */
getType([])     // "Array" typeof []是object,因此toString返回
getType('123')  // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null)   // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined)   // "undefined" typeof 直接返回
getType()            // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g)      //"RegExp" toString返回
复制代码

Guess you like

Origin juejin.im/post/7086281788464562213