重学前端——JS基础

1.JavaScript规定了几种语言类型?

  • Number
  • String
  • Boolean
  • undefined
  • Null
  • Object
  • Symbol
  • Set
  • Map
  • BigInt(一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这本来是 Javascript中能够用 Number 表示的最大数字。BigInt 能够表示任意大的整数)

2.JavaScript对象的底层数据结构是什么,在内存中的具体存储形式?

  • JavaScript基本类型数据都是直接按值存储在栈中的(Undefined、Null、不是new出来的布尔、数字和字符串),每种类型的数据占用的内存空间的大小是肯定的,并由系统自动分配和自动释放。这样带来的好处就是,内存能够及时获得回收,相对于堆来讲 ,更加容易管理内存空间。javascript

  • JavaScript引用类型数据被存储于堆中 (如对象、数组、函数等,它们是经过拷贝和new出来的)。其实,说存储于堆中,也不太准确,由于,引用类型的数据的地址指针是存储于栈中的,当咱们想要访问引用类型的值的时候,须要先从栈中得到对象的地址指针,而后,在经过地址指针找到堆中的所须要的数据。java

3.Symbol类型在实际开发中的应用、可手动实现一个简单的Symbol。

Symbol表示独一无二的值(须要注意的是经过 Symbol()方法建立值的时候不能使用 new 操做符,缘由是经过 new 实例化的结果是一个 object 对象,而不是原始类型的 symbol)数组

  • 实际开发中,当遇到比较复杂的对象或是须要多人共同维护的对象类型数据,容易产生属性名的重复,使用symbol能够避免这样的问题:
const opt1 = Symbol('key');
const opt2 = Symbol('key');
const obj = {
    [opt1]: 'value',
    [opt2]: 'value',
}
// obj:{Symbol(key): "value", Symbol(key): "value"}
复制代码
  • 第二种状况是模拟类中的私有变量
// a.js

const privateKey = Symbol('key')
class myClass{
    constructor(){
        this.name = 'test'
        // 由于Symbol独一无二的特性,此处的属性只能在a.js中被访问,
        // 新建出来的实例也没法访问该属性,本质上是没法访问privateKey。
        this[privateKey] = 'strange' 
    }
}

复制代码

4.基本类型对应的内置对象,以及他们之间的装箱拆箱操做?

如 String、Number、Boolean、Object、Function、Array、Date、RegExp、Error。实际上这些是一些内置函数,这些内置函数能够当作构造函数来使用,从而建立一个对应子类型的新对象。安全

  • 所谓的装箱,是指将基本数据类型转换为对应的引用类型的操做。而装箱又分为隐式装箱和显式装箱。
  • 拆箱就和装箱相反。是指把引用类型转换成基本的数据类型。一般经过引用类型的valueOf()和toString()方法来实现。

具体不展开,详见 juejin.cn/post/684490…markdown

5.null和undefined的区别

  • undefined的字面意思是:未定义的值。在试图读取未定义或者定义了未赋值的变量时会返回。数据结构

  • null的字面意思是:空值。在内存中能够表示为栈中的指针地址没有指向堆中的内存对象。(在JS最初的实现中,中的值是由一个表示类型的标签和实际数据值表示的,对象的类型标签是0。因为null表明的是空指针0x00,所以,null的类型标签也成为了 0,typeof null就错误的返回了"object")函数

6.至少能够说出三种判断JavaScript数据类型的方式,以及他们的优缺点,如何准确的判断数组类型?

  1. typeof
  • 优势:书写简单,易于理解
  • 缺点:只能区分基本数据类型,没法判断复杂数据类型,如null,Array,Date等(function有效)
  1. instanceof
  • 优势:能够判断一个实例是不是其父类型或者祖先类型的实例
  • 缺点:左侧必须为对象(没法判断null,undefined),当原型链发生变更时会判断错误
  1. Object.prototype.toString.call
  • 优势:能够直接输出数据类型字符串,易于判断,适用全部数据类型
  • 缺点:书写麻烦

判断数组:Object.prototype.toString.call(new Array()) === '[object Array]'post

7.出现小数精度丢失的缘由,JavaScript能够存储的最大数字、最大安全数字,JavaScript处理大数字的方法、避免精度丢失的方法?

缘由:JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit。1位用来表示符号位,11位用来表示指数,52位表示尾数。ui

由于在计算机最底层,数值的运算和操做都是采用二进制实现的,因此计算机没有办法精确表示浮点数,而只能用二进制近似相等的去表示浮点数的小数部分。this

0.1 >> 0.0001 1001 1001 1001…(1001无限循环)
0.2 >> 0.0011 0011 0011 0011…(0011无限循环)

0.1+0.2 = 0.01001100110011001100110011001100110011001100110011001110
转十进制0.30000000000000004
复制代码

当进行计算或其余操做时时,四舍五入(逢1进,逢0舍)将会致使最终的运算结果存在误差。

而大整数也存在一样的问题,由于表示尾数的尾数只有52位,所以 JS 中能精准表示的最大整数是 Math.pow(2, 53),即十进制9007199254740992。(ES2015的BigInt就是用来解决大数问题)

能够引入Math.js等一些专门处理此问题的三方库来解决精度丢失。

相关文章
相关标签/搜索