前端面试 第一篇 js数据类型

1,008 阅读6分钟

作为一个不专业只会C + V的程序员,今天终于来掘金更新自己的前端小知识了~ 不秃头的我压力山大哦,这段时间在着手面试,就简单的做了一些梳理,作为入门! ~

images.jpg
并不是所有知识都需要看,希望是一个抛砖引玉的作用, ~

数据类型

值类型(基本类型)

  • Number (数字)
  • String (字符串)
  • Boloean (布尔值)
  • Null (空)
  • Undefined (未定义)
  • BigInt (可以表示任意大的整数)
  • Symbol(表示独一无二的值)

基本数据类型的特点: 直接存储在栈(stack)中的数据

引用数据类型(对象类型):

  • Array(数组)
  • Function(函数)
  • Object(对象)
  • Date(日期)
  • RegExp(正则)

引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里

栈内存

主要用于存放基本类型和对象变量的指针,算是一种简单的储存; 栈内存自动分配相对固定大小的内存空间,并由系统自动释放;

堆内存

主要用于存放引用类型,存储的对象类型数据对于大小在这方面都是未知的; 堆内存是动态分配内存,内存大小不一,也不会自动释放

1661163137209.jpg

那么如何判断数据类型❓

typeof: 在基本数据类型(null除外)和Function时,返回其对应类型;对于引用数据类型(Function除外)都返回为object;

instanceof:无法判断基本数据类型;对于引用数据类型(除判断数据类型是否是Objcet类型外)均可;

constructor: 在基本数据类型(null 与 undefined 除外)/引用数据类时,均返回其对应类型;

Object.prototype.toString: 无论基本数据类型还是引用类型返回其对应类型;

typeof

  • typeof 判断基本数据类型:null 返回 object 其余均返回对应数据类型;
    const string = '321'; 
    const number = 321; 
    const boolean = true; 
    const enty = null; 
    const unassigned = undefined;
    const symbol = Symbol(); 
    const bigin = BigInt(1236587489845500); 
    
    console.log(typeof string) // string 
    console.log(typeof number) // number 
    console.log(typeof boolean) // boolean 
    console.log(typeof enty) // object 
    console.log(typeof unassigned) // undefined 
    console.log(typeof symbol) // symbol 
    console.log(typeof bigin) // bigin
    
  • typeof 判断引用数据类型:function 返回 function 其余均返回object;
    // typeof 判断引用数据类型
    const arr = [1,2,3,4];
    const obj = {name: '1212'}; 
    const fun = () => {}; 
    const dates = new Date(); 
    const regexp = /[0-9]{1,2}/
    
    console.log(typeof arr) // object 
    console.log(typeof obj ) // object 
    console.log(typeof fun ) // function 
    console.log(typeof dates ) // object
    console.log(typeof regexp ) // object
    

instanceof

  • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上; 基本数据类型 不存在prototype 因此不能使用 instanceof 来判断基本数据类型;

    const arr = [1,2,3,4];
    const obj = {name: '1212'}; 
    const fun = () => {}; 
    const dates = new Date(); 
    const regexp = /[0-9]{1,2}/
    
    console.log(arr instanceof Array) // true  
    console.log(obj instanceof Object) // true 
    console.log(fun instanceof Function) // true 
    console.log(dates instanceof Date) // true
    console.log(regexp instanceof  RegExp) // true
    
    
    console.log(regexp instanceof  Date) // false
    console.log(regexp instanceof  Function) // false
    

    ❗❗ 以上 使用instanceof 进行判断引用数据类型,实则是问题的; 让我们一起探索下:

  • instanceof 进行判断引用数据类型 存在的问题:

    const arr = [1,2,3,4];
    const obj = {name: '1212'}; 
    const fun = () => {}; 
    const dates = new Date(); 
    const regexp = /[0-9]{1,2}/;
    
    // 所有引用数据都是 Object 的实例,因此通过 instanceof 操作符检测任何引用数据和Object 构造函数都会返回 true
    console.log(arr instanceof Object) // true  
    console.log(obj instanceof Object) // true 
    console.log(fun instanceof Object) // true 
    console.log(dates instanceof Object) // true
    console.log(regexp instanceof  Object) // true
    
    
    console.log(regexp instanceof  Date) // false
    console.log(regexp instanceof  Function) // false
    

    为什么出现以上问题呢? 我们就需要了解一下 instanceof的原理:

    instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上;

    其实现逻辑如下:

    // 其中 value 表示 instance 左边的数据, target表示 instance 右边边的数据
    function _instance(value, target) {
        let proto = value.__proto__; // 对象的原型
        let prototype = target.prototype; // 构造函数的 prototype 对象
    
        // 判断构造函数的 prototype 对象是否在对象的原型链上
        while (true) {
            if (!proto) return false;
            //TODO: 重点:当 proto 严格等于 prototype 时,返回 true
            if (proto === prototype) return true;
            proto = proto.__proto__;
        }
    }
    
    // 实验一下
    console.log(_instance([1,2,3], Array)); // true
    console.log(_instance([1,2,3], Function)); // false
    

constructor

  • constructor 判断基本数据类型

    // constructor 判断基本数据类型
    const string = '321'; 
    const number = 321; 
    const boolean = true; 
    const enty = null; 
    const unassigned = undefined;
    const symbol = Symbol(); 
    const bigin = BigInt(1236587489845500);
    // null 与 undefined 不存在 原型
    console.log(string.constructor === String) // true 
    console.log(string.constructor === String) // true 
    console.log(number.constructor === Number ) // true 
    console.log(boolean.constructor === Boolean ) // true 
    console.log(symbol.constructor === Symbol) // true
    console.log(bigin.constructor === BigInt) // true
    
  • constructor 判断引用数据类型

      // constructor 判断引用数据类型
        const arr = [1,2,3,4];
        const obj = {name: '1212'}; 
        const fun = () => {}; 
        const dates = new Date(); 
        const regexp = /[0-9]{1,2}/
    
        console.log(arr.constructor === Array) // true 
        console.log(obj.constructor === Object ) // true 
        console.log(fun.constructor === Function ) // true 
        console.log(dates.constructor ===  Date) // true
        console.log(regexp.constructor === RegExp) // true
    
  • constructor 存在的问题
    如果一个对象改变了原型,constructor 的判断还准确吗? 我们试一下:

       function Functions() {}
       // 改变原型
       Functions.prototype = new Array();
       let tempF = new Functions();
       console.log(tempF.constructor === Functions); // false
       console.log(tempF.constructor === Array); // true
    

    如果对象改变了原型,那么使用constructor不再准确;

Object.prototype.toString

Object.prototype.toString 统一返回格式为“[object Xxx]”的字符串;

  • Object.prototype.toString 判断基本数据类型 (统一返回格式“[object Xxx]”的字符串;)
    // 由于返回格式“[object Xxx]”的字符串,需要对Object.prototype.toString进行处理
    // 检测数据类型功能函数
    const checkedType = (target) => Object.prototype.toString.call(target).replace(/\[object (\w+)\]/, "$1").toLowerCase();
    
    // 判断基本数据类型
    const string = '321'; 
    const number = 321; 
    const boolean = true; 
    const enty = null; 
    const unassigned = undefined;
    const symbol = Symbol(); 
    const bigin = BigInt(1236587489845500);
    
    console.log(checkedType(string)); // string
    console.log(checkedType(number)); // number
    console.log(checkedType(boolean)); // boolean
    console.log(checkedType(enty)); // null
    console.log(checkedType(unassigned)); // undefined
    console.log(checkedType(symbol)); // symbol
    console.log(checkedType(bigin)); // bigin
    
    • Object.prototype.toString 判断引用数据类型
    // 由于返回格式“[object Xxx]”的字符串,需要对Object.prototype.toString进行处理
    // 检测数据类型功能函数
    const checkedType = (target) => Object.prototype.toString.call(target).replace(/\[object (\w+)\]/, "$1").toLowerCase();
    
    // 判断引用数据类型
    const arr = [1,2,3,4];
    const obj = {name: '1212'}; 
    const fun = () => {}; 
    const dates = new Date(); 
    const regexp = /[0-9]{1,2}/
    
    console.log(checkedType(arr)); // array
    console.log(checkedType(obj)); // object
    console.log(checkedType(fun)); // function
    console.log(checkedType(dates)); // date
    console.log(checkedType(regexp)); // regexp
    

类型转换

JavaScript 变量可以转换为新变量或其他数据类型:

  • 通过使用 JavaScript 的函数
  • 通过 JavaScript 自身自动转换

Number ===> String

  • String()
let temp = 123;
let tempString = String(temp);
console.log(typeof temp)  // number
console.log(typeof tempString);  // string
  • toString()
let temp = 123;
let tempString = temp.toString();
console.log(typeof temp)  // number
console.log(typeof tempString);  // string

还有很多方法可以将Number转成String, 这里就不一一介绍了哦;不然你们觉得我只会基础的,吼吼吼~~~

  • toExponential()
  • toFixed()
  • toPrecision()
  • ...

Boolean ===> String

  • String()
let Boolean = true;
let tempString = String(Boolean);
console.log(typeof Boolean)  // boolean
console.log(typeof tempString);  // string
  • toString()
let Boolean = false;
let tempString = Boolean.toString();
console.log(typeof Boolean)  // boolean
console.log(typeof tempString);  // string

Date ===> String

  • String()
let currentDate = new Date();
let tempString = String(currentDate);
console.log(currentDate instanceof Date)  // true
console.log(typeof tempString);  // string
  • toString()
let currentDate = new Date();
let tempString = currentDate.toString();
console.log(currentDate instanceof Date)  // true
console.log(typeof tempString);  // string
  • ...

String ===> Number

  • Number()
let String = '34122';
let tempNumber = Number(String);
console.log(typeof String)  // string
console.log(typeof tempNumber);  // number
  • 一元运算符 +
let String = '34122';
let tempNumber = + String;
console.log(typeof String)  // string
console.log(typeof tempNumber);  // number
// 如果变量不能转换,它仍然会是一个数字,但值为 NaN (不是一个数字)
let name = 'Jack';
let nameToNumber = + name;
console.log(nameToNumber) // nameToNumber 是一个数字 (NaN)
  • parseFloat() 返回一个浮点数
  • parseFloat() 返回一个整数
  • ...

Boolean ===> Number

  • Number()
let BoleanTrue = true;
let BooleanFalse = false;
let NumberTrue = Number(BoleanTrue);
let NumberFalse = Number(BooleanFalse);
console.log(typeof BoleanTrue, BoleanTrue); // boolean, true
console.log(typeof BooleanFalse, BooleanFalse); // boolean, false
console.log(typeof NumberTrue, NumberTrue); // number,  1
console.log(typeof NumberFalse, NumberFalse); // number, 0

综上所述,就是本期JavaScript的基本数据类型,选择一个最适合的判断数据类型的方法 希望对你有所帮助哦~~~

前端学习虽然辛苦,但是总有收获的时候,当自己看到了成果,会不自觉的开心; 但是一抬头看见了产品经理心里顿时:~~~, 一万匹马奔腾而过~~~~

下载.jpg
带上耳机听一首歌走咯,下班咯!明天见,兄弟们