【前端面试总结】基础数据类型总结(包含手写深浅拷贝,flat)

257 阅读5分钟

词法

es5中就有的数据类型:

string number boolen null(空指针) undefined Object(function object array)

es6及之后新增:

symbol(表示唯一变量); bigInt(大数字)

数据类型

1.值类型与引用类型有什么区别?

值类型是除object(引用类型)外的基础数据类型,他在计算机中表示栈内存中存储的一个值,而引用类型代表一个栈内存指针,指向一个堆内存对象值。值类型按值传递,引用按引用关系传递,相关有浅拷贝与深拷贝。

1.1 深浅拷贝的区别 1.浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
2.深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝

1.2 手写深拷贝与浅拷贝
浅拷贝:

//循环赋值
let shallowClone = function(obj){
 let res = Object.create(null)
 for (const key in obj) {
   if (obj.hasOwnProperty(key)) {
     const element = obj[key];
     res[key] = element;
   }
 }
 return res;
}

深拷贝:

let deepClone = function(obj){
  //后面需要使用typeof,考虑null情况
 if(obj === null)return null;
 //考虑date和正则
 if(obj instanceof Date)return new Date(obj);
 if(obj instanceof RegExp)return new RegExp(obj);
 if (typeof obj !== "object") return obj;
 let res = Object.create(null);//写在在这里可以避免频繁创建对象
 for (const key in obj) {
   if (obj.hasOwnProperty(key)) {
     const element = obj[key];
     res[key] = deepClone(element);
   }
 }
 return res;
}

2.如何判断值的类型

对于基础类型可以使用typeof关键字进行判断,其中null会输出object(因为null代表空指针,在js中作为Object构造函数的顶层原型),array类型使用Array.isArray(),object使用value.tostring()

2.1 判断全类型函数(基础版)

  let typeCheck = function(value){
    if(!value){
      if(Array.isArray(value)){
        return "array"
      }
      if(value.toString()==="[object Object]"){
        return "object"
      }
    }
    return !value && typeof value === 'object'?"null":typeof value
  }

2.2 判断全类型函数(包括自带构造函数)

  let typeAllCheck = function(value){
    let type = Object.prototype.toString.call(value)
    return type.slice(7,-1)
  }

2.3 几种数据类型的判断方法

1.typeof 不能精确判断null,引用类型

2.instanceof 判断a是否为b的实例 用法:a instaceof b,但由于原型链的关系,一个数组可以既是Array的实例也是Object的实例

3.constructor 原理与instanceof一致,通过构造函数来判断类型,不过不受原型链影响

4.tostring(),调用对象内置的tostring方法判断,此种方法除了对象可以直接使用,其他需要Object.prototype.tostring.call()来使用

3 基础数据类型转换

结合工作学习中的例子去解释,注意点在显示转换和隐式转换

4 ES6及之后中各数据类型都新增了那些方法,扩展 (常用方法)

4.1 字符串

1.模板字符串
2.支持for...of遍历
3.标签模板 在函数后跟模板字符串,会调用此函数来处理

alert`hello`

这里面有个细节,在函数调用时,并不是把参数当做字符串来调用,而是作为多个参数调用,例子:

alert`hello`
//等同于
alert(['hello'])

let w = "world"
alert`hello${w}`
//等同于
alert(['hello'],w)

4.includes(), startsWith(), endsWith()

includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

5.trimStart(),trimEnd()
es2019新增,用于消除头部和尾部空格

4.2数值的新增方法

1.isFinite()和isNaN()

全局方法中也有这两个判断函数,区别是全局会做隐式转换,而Number如果不是数字会直接返回false

2.isInteger() 判断是否为整数

4.3 数组的扩展方法

1.Array.from() 把类数组对象(例如arguments,nodeList对象,带有length属性并且value为数值,其他为数字key的对象)转换为数组 2.Array.of() 用于将一组值转换为数组

Array.of(1,2,3)
// [1,2,3]

3.copyWithin() 将制定成员复制到同数组指定位置,并覆盖原位置元素

arr.copyWithin(target[, start[, end]])

4.find和findIndex
用于查找满足某一条件的值(find)和其下标(findIndex)

5.entries(),keys() 和 values() keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。都返回一个由遍历结果组成的数组,其中键值对会以

[[kes,value],[kes,value]]

的形式组成

6.includes
用于返回一个布尔值表示数组是否包含给定的值

7.flat和flatMap
flat()用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响,参数为拉平的层数,默认为1
flatMap()方法对原数组的每个成员执行一个函数(相当于执行map()),然后对返回值组成的数组执行flat()方法

7.1 手写flat的polyfill

let myFlat = function(arr=[],depth=1){
    let res = [];
    (function flat(arr,depth){
      for (const iterator of arr) {
        if(Array.isArray(iterator)){
          if(depth >0)flat(iterator,depth-1)
        }else{
          //forof不能跳过空元素,要手动执行
          iterator !== void 0 &&res.push(iterator)
        }
      }
    })(arr,depth)
    return res;
}

MDN上还有很多类似方法可用于polyfill

4.3 对象的扩展方法

对象也包含entries(),keys() 和 values(),用法基本一致

  1. is
    比较两个值是否相等,注意点是其会判断NaN等于自身,+0等于-0
  2. Object.assign
    用于合并对象,参数为目标对象,源对象,将源对象所有可枚举属性赋值给源对象,返回目标对象,此种赋值是一种浅拷贝
    3.Object.fromEntries()
    是Object.entries()的逆操作

关于es5所包含的各种方法因为使用的比较频繁就不单独列出
对象,函数,数组将陆续总结
如有错误之处,期待指正