前端面试题总结——JS篇

一、说说JavaScript中的数据类型?存储上有什么差别?

1、数据类型

  • 基本类型
    • number:数值类型
      • 十进制:let intNum = 55
      • 八进制(零开头):let num1 = 070
      • 十六进制(0x开头):let hexNum1 = 0xA
      • NaN:特殊数值,意为“不是数值”
    • string:字符串类型
    • boolean:布尔值,true或false
    • undefined:表示未定义
    • null:空值
    • symbol: 是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发送属性冲突的危险
  • 复杂类型(复杂类型统称为Object)
    • Object:对象
    • Array:数值
    • Function:函数
    • 其他引用类型(Date、RegExp、Map、Set等)

2、存储区别

基本数据类型和引用数据类型存储在内存中的位置不同

  • 基本类型的值存放在栈中
  • 引用类型对应的值存储在堆中,在栈中存放的是指向堆内存的地址

当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型还是引用类型值,不同的类型数据导致赋值变量时的不同:

  • 基本类型赋值,是生成相同的值,两个对象对应不同的地址
  • 复杂类型赋值,是将保存对象的内存地址赋值给另一个变量,也就是两个变量指向堆内存同一个对象

二、说说你了解的JS数据结构?

1、什么是数据结构?

数据结构是计算机存储、组织数据的方式。

数据结构意味着接口或封装:一个数据结构可被视为两个函数之间的接口,或者是由数据类型联合组成的存储内容的访问方法封装。

常见的数据结构:

  • 数组(Array)
    • 数组是最最基本的数据结构,很多语言都内置支持数组。
    • 数组是使用一块连续的内存空间保存数据,保存的数据的个数载非配内存的时候就是确定的
  • 栈(Stack)
    • 栈是一种遵循后进先出(LIFO)原则的有序集合
    • 在栈里面,新元素都接近栈顶,旧元素都接近栈底
    • 每次加入新的元素和拿走元素都在顶部操作 

前端面试题总结——JS篇_第1张图片

  • 队列(Queue)
    • 队列是遵循先进先出(FIFO)原则的一组有序的项
    • 队列在尾部添加新元素,并从顶部移除元素
    • 最新添加的元素都在队列的尾部
  • 链表(Linked List)
    • 链表也是一种列表,已经设计了数组,为什么还需要链表呢?
    • JavaScript中的数组的主要问题是他们被实现成了对象,与其他语言的数组相比效率较低,如果你发现数组在实际使用时很慢,可以考虑使用链表
    • 使用条件:
      • 链表几乎可以用在任何可以使用一堆数组的情况中
      • 如果需要随机访问,数组仍然是最好的选择
  • 字典
    • 字典是一种以键-值对存储数据的数据结构,js中的Object类就是以字典的形式设计的
  • 散列表(Hash table)
    • 也称为哈希表,特点是在散列表上插入、删除和取用数据都非常快
  • 树(Tree)
  • 图(Graph)
  • 堆(Heap)

三、DOM常见的操作有哪些?

  • 创建节点:
    • createElement:创建一个新的HTML元素,例如 document.createElement('div')
    • createTextNode:创建一个新的文本节点,例如 document.createTextNode('Hello world')
    • createDocumentFragment:创建一个文本碎片,用于存储临时节点,然后将文本碎片的内容一次性添加到DOM中,例如document.createDocumentFragment()
  • 查询节点:
    • getElementById:通过id获取元素,例如document.getElementById('myId')
    • getElementByClassName:通过类名获取一组元素,例如document.getElementsByClassName('myClass')
    • getElementByTagName:通过标签名获取一组元素,例如document.getElementsByTagName('p')
    • querySelector:根据css选择器获取单个元素,例如document.querySelector('.element')
    • querySelectorAll:根据css选择器获取一组元素,例如document.querySelectorAll('p')
  • 更新节点:
    • setAttribute:修改元素的属性或样式,例如element.setAttribute('class', 'newClass')来修改元素的class属性
    • textContent:修改文本内容,例如element.textContent = 'new content'来更新元素的文本内容‌
  • 添加节点:
    • appendChid:将子节点添加到父节点的最后一个子节点,例如parentElement.appendChild(newElement)。
    • insertBefore:将子节点插入到指定位置的前面,例如parentElement.insertBefore(newChild, referenceChild)
  • 删除节点:
    • removeChild:从父节点中移除子节点,例如parentElement.removeChild(childElement)
    • replaceChild:替换子节点,例如parentElement.replaceChild(newChild, oldChild)‌
  • 事件处理:
    • 事件监听器:例如使用 element.addEventListener('click',function(){...})

四、说说你对BOM的理解,常见的BOM对象你了解哪些?

1、BOM与DOM的定义?

BOM(浏览器对象模型):用于操作浏览器窗口行为,无统一标准

DOM(文档对象模型):用于操作网页内容结构,W3C标准

DOM BOM
文档对象模型 浏览器对象模型
DOM就是把[文档]当做一个[对象]来看待 把[浏览器]当做一个[对象]来看待
DOM的顶级对象是 document BOM的顶级对象是 window
DOM主要学习的是操作页面元素 BOM学习的是浏览器窗口交互的一些对象
DOM是W3C标准规范 BOM是浏览器厂商在各自浏览器上定义的,兼容性较差

常见的BOM对象:

  • window:提供了许多方法用于控制窗口,如移动,调整大小,滚动等
  • location:用于获取当前页面的url信息,并可以重定向到新的页面
    • reload:重新加载当前页面
    • assign(url):加载新的文档
    • replace(url):用新的文档替换当前文档,不会在历史记录中留下记录
    • toString(url):返回完整的url
  • navigator:包含有关浏览器的信息,如浏览器版本,语言等
  • screen:包含有关屏幕的信息
  • history:包含用户(在窗口中)访问过的url历史记录

五、== 和 === 的区别,分别在什么情况下使用?

等于操作符用两个等于号(==)表示,如果操作数相等,则会返回 true

全等操作符用三个等于号(===)表示,需要先判断类型,类型不同时,直接返回false,类型相同时,比较值,值相同,则会返回true,否则为false

六、typeof与instancef区别?

  typeof instanceof
用途 主要用于检测基本数据类型以及特殊类型 用于检测某个对象是否是另一个对象的实例,基于原型链的检查
返回值 返回一个表示类型的字符串 返回一个布尔值
局限性 对于复杂引用类型(如数组,对象),typeof会返回‘object’,无法准确判断对象的具体类型 无法检测基本数据类型

此外,typeof null 会返回 'object',这是一个历史遗留问题

七、javaScript原型,原型链?有什么特点?

1、原型

JavaScript常被描述为一种基于原型的语言,每个对象都有一个内部属性 __proto__ , 这个属性指向该对象的原型对象,包含了可以由该对象继承的方法和属性,例如,所有的函数都有一个 prototype 属性,这个属性指向一个对象,该对象包含了可以由所有该函数创建的对象实例共享的方法和属性。

每个对象都拥有一个原型对象,当试图访问一个对象的属性时,他不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象原型的原型,依次层层向上搜索,知道找到一个匹配的属性或者到达原型链的末尾。

2、原型链

原型链是由对象和他们的原型组成的链,当访问一个对象的属性和方法时,他不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象原型的原型,依次层层向上搜索,知道找到一个匹配的属性或者到达原型链的末尾(通常是Object,prototype)。如果最终在原型链的顶端也找不到所需的属性或方法,则会返回 undefined。

八、说说你对作用域链的理解?

1、作用域

作用域是变量和函数生效的区域或集合,换句话说,作用域决定了代码区块中变量和其他资源的可见性,我们一般将作用域分成:

  • 全局作用域
    • 任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问
  • 函数作用域
    • 函数作用域也叫局部作用域,如果一个变量是在函数内部声明的,它就在一个函数作用域下面,这些变量只能在函数内部访问,不能在函数以外去访问
  • 块级作用域
    • ES6引入了 let 和 const 关键字,和 var 关键字不同,在大括号中使用 let 和 const 声明的变量存在于块级作用域中,在大括号之外不能访问这些变量

2、词法作用域

词法作用域,又叫静态作用域,变量被创建时就确定好了,而非执行阶段确定的,也就是说我们写好代码时他的作用域就确定了,JavaScript 遵循的就是词法作用域

3、作用域链

当在 JavaScript 中使用一个变量的时候,首先JavaScript 引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到他的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域,如果在全局作用域里仍然找不到该变量,他就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错

九、谈谈对this对象的理解?

在JavaScript中,this 是一个动态绑定的关键字,其指向取决于函数的调用方式,以下是主要情况的总结:

  • 全局作用域中的 this
    • 在全局作用域中, this 指向全局对象(浏览器中为 window , node.js 中为 global)
  • 函数调用中的 this 
    • 普通函数:非严格模式下指向全局对象,严格模式下为 undefined
    • 箭头函数:继承父作用域的 this ,无法通过调用方式改变
  • 方法调用中的 this
    • 当函数作为对象的方法调用时, this 指向调用该方法的对象
  • 构造函数中的 this
    • 使用 new 调用构造函数时, this 指向新创建的实例对象
  • 显式绑定
    • 通过 call , apply 或 bind 可以强制指定 this 的指向
  • 事件处理函数中的 this
    • 在DOM事件处理函数中, this 通常指向触发事件的元素
  • 特殊函数
    • 匿名函数:默认指向全局对象,可通过闭包保存外部 this
    • 间接调用:如(obj.method = obj.method)() 会导致 this 丢失

总结:this 的绑定规则优先级为 new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定 ,箭头函数例外,其 this 在定义时确定

十、说说 new 操作符具体干了什么?

在JavaScript中用于创建一个给定构造函数的实例对象

当使用 new 操作符调用构造函数是,他会执行以下操作:

  1. 创建一个新的空对象:这个对象将继承构造函数的原型
  2. 设置原型链:新对象的内部[protottype](在ES6 中可以通过 Object.getPrortotypeOf 方法访问)被设置为构造函数的 prototype 属性。这样,新对象可以访问构造函数原型对象中定义的属性和方法
  3. 绑定this并执行构造函数:将新对象绑定到构造函数的 this ,然后执行构造函数。构造函数可以使用 this 为新对象添加属性和方法
  4. 返回值处理:如果构造函数没有返回其他对象,则 new 操作符返回新创建的对象实例,如果有构造函数返回一个对象,则返回该对象

new 操作符的必要性及其解决的问题:

  1. 自动设置原型链:无需手动设置新对象的原型, new 自动将新对象的原型设置为构造函数的 prototype 
  2. 自动绑定 this :在构造函数中, this 自动指向新创建的对象,使得属性和方法的添加变得简单
  3. 简化实例化过程:通过 new ,可以轻松创建多个具有相同结构和行为的对象实例

十一、bind、call、apply的区别?如何实现一个bind?

首先,

你可能感兴趣的:(前端,javascript,开发语言)