JavaScript面试基础

1.介绍js的基本数据类型

js一共有六种基本数据类型,分别是Undefined,null,boolean,number,string,还有ES6新增的Symbol和ES10中新增的BigInt类型。

Symbol代表创建后独一无二且不可变的数据类型,它的出现可能是为了解决可能出现的全局变量冲突的问题(个人观点)

BigInt是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数已经超出了Number能够表示的安全整数范围。

2.JavaScript有几种类型的值?

JavaScript可以分为两种类型的值,一种是基本数据类型,一种是复杂数据类型。

两种类型的主要区别是:存储位置不同

原始数据类型直接存储在**栈(stack)**中的简单数据段,占据空间小,大小固定,属于被频繁使用数据,所以放入栈中存储。

引用数据类型存储在**堆(heap)**中的对象,占据空间大,大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

3.什么是堆?什么是栈?它们之间有什么区别和联系?

堆和栈的概念存在于数据结构中和操作系统内存中。

在数据结构中,栈中数据的存取方式为先进后出。而堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。完全二叉树是堆的一种实现方式。

在操作系统中,内存被分为栈区和堆区。

栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

堆区内存一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收。

4.null和undefined的区别?

首先undefinednull都是基本数据类型,这两个基本数据类型分别都只有一个值,就是undefined和null。

undefined代表的含义是未定义null代表的含义是空对象。一般变量声明了但还没有定义的时候会返回undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。

undefined在js中不是一个保留字,这意味着我们可以使用undefined来作为一个变量名,但是这样做是非常危险的,它会影响我们对undefined的值的判断。但是我们可以通过一些方法获得安全的undefined值,比如说void 0。

当我们对两种类型使用typeof进行判断时,null类型化会返回"object",这是一个历史遗留的问题。当我们使用双等号对两种类型的值进行比较时会返回true,使用三个等号会返回false

5.如何获取安全的undefined值?

因为undefined是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响undefined的正常判断。

表达式void ___没有返回值,因此返回结果是undefined。void并不改变表达式的结果,只是让表达式不返回值。按惯例我们用void 0来获得undefined。

6.prototype和_proto_的关系是什么?

  1. prototype用于访问函数的原型对象
  2. _proto_用于访问对象实例的原型对象(或者使用Object.getPrototypeOf()
1
2
3
function Test(){}
const test = new Test()
test._prototype_ == Test.prototype //true

也就是说,函数拥有prototype属性,对象实例拥有_proto_属性,它们都是用来访问原型对象的。

函数有点特别,它不仅是个函数,还是个对象。所以它也有_proto_属性

7.什么是闭包?

闭包是指有权访问另一个函数作用域中的变量的函数

1
2
3
4
5
6
7
function sayHi(name){
return ()=>{
console.log(`Hi! ${name}`)
}
}
const test = sayHi('xiaoming')
test() //Hi!xiaoming

虽然sayHi函数已经执行完毕,但是其活动对象也不会被销毁,因为test函数仍然引用着sayHi函数中的变量name,这就是闭包

(但也因为闭包引用着另一个函数的变量,导致另一个函数即使不使用了也无法销毁,所以闭包使用过多,会占用较多的内存,这是一个副作用)

利用闭包实现私有属性

1
2
3
4
5
6
7
const test = (function(){
let value = 0
return {
getVal(){return value},
setVal(val){value = val}
}
})()

以上代码,实现了一个私有属性value,它只能用过getVal()来获取值,通过setVal(val)来设置值。