• 前端面试题(JS部分)


    一, 数据类型

    1,什么是引用类型,值类型?

    值类型key与value存储在栈中(量小)
    引用类型在栈存储的引用地址,在堆中存储是数据(量大)
    把引用类型赋值给一个变量,是吧变量的引用地址指向引用类型堆中地址

    2,哪些值类型

    • String字符,
    • Number数字,
    • Boolean布尔,
    • undefined未定义
    • null空(特殊)
    • Symbol符号

    3,哪些引用类型

    • Object对象
    • Array数字
    • Function 函数
    • Map图
    • Set集合

    4,判断数据类型

    • typeof 类型
    • instanceof 实例
    • constructor 构造函数
    • Array.isArray() 是否为数组
    • Object.prototype.toString.call(obj) 原型

    5,typeof判断

    typeof “abc” string
    typeof 123 number
    typeof true boolean
    typeof undefined undefined
    typeof null object
    typeof Symbol() symbol
    typeof {} object
    typeof [] object
    typeof function(){} function
    typeof new Map() object
    typeof new Set() object

    适合判断 值了与引用类型 不能判断具体引用类型

    6,instanceof

    [] instanceof Array true
    [] instanceof Object true
    {} instanceof Array false
    {} instanceof Object true

    1. 判断是否是其原型链上的实例 只要这个构造函数在原型链都返回true
    2. ([] 由Array创建的,Array是 Object的子类, instanceof Array和 Object 都返回true)

    7,construtor

    判断实例对象构造函数
    [].constructor === Array true 最精确

    最精确

    Object.prototype.toString.call(obj).slice(8,-1)
    返回数据的精确类型

    二,浅拷贝 / 深拷贝

    1, 浅拷贝

    扩展{...obj}
    for遍历
    Object.assgin()
    
    • 1
    • 2
    • 3

    2,深拷贝

    2.1,JSON.parse(JSON.stringify(数据))

    json数据类只支持 布尔,字符串,数字 null,undefined array object 会忽略函数 等其他类型数据

    2.2, 通过判断类型 递归深拷贝

    递归就是函数调用自己
    一定要有结束条件

    三,隐式转换

    看符号
    +

      • 字符串连接符号 会尝试把其他类型转换为 字符串
    1. ±*/ == 会尝试把其他类型转换为数字
      转换失败 NaN
      false 转换为 0
      true 转换 1

    3.<>= <= ! != == 判断与逻辑返回会尝试把其他类型转换布尔值
    falsely变量转换为false “” null NaN undefined 0 转换为false

    四,严格等于

    1. === 判断类型和值是否都相对

    2. 应该在任何时候都使用=== (当判断是否为null或者为undefined可以为特例)

    3. null === null true

    4. == 判断隐式转换后的值 “100” == 100 // true null == undefined //true 0 == false //true 特例:NaN === null // false

    5. {} == {} // false [] == {} //false 指向不同的内存地址

    五,if判断

    1. if()中判断的是否为truely变量
    2. falsely变量:false “” 0 NaN undefined null 两次取反 !!a得到结果为false
    3. 除了falsely变量其他都为truely变量

    六, 逻辑且逻辑或

    A||B
    A为真(truely) 结果为A ,否则结果为B
    A&&B
    A为假(falsely) 结果为A,否则结果为B
    判断对象
    if(a&&a.b&&a.b.c){}
    if(a?.b?.c){}
    如果有a并且有a.b并且有a.b.c
    if(a.b.c){}

    七,原型与原型链

    1,名词

    1. 类:(创建对象实例的模板) 本质上都是函数

      	构造函数 用new来执行的函数
      	class xxx { }
      
      • 1
      • 2
    2. 实例:由类创建的对象(本质上讲就是对象)

    3. 显示原型

    类/构造函数都一个显示显示原型protype (本质是就是个对象)

    1. 隐式原型

    每个实例都有一个隐私原型__proto__

    1. 显与隐关系

    类显示原型protype等于其创建的实例的隐式原型__proto__

    1. 原型链

    查找对象实例的方法和属性时,先在自身找,找不到则沿着__proto__向上查找,__proto__形成的链条关系我们称为原型链(实现了js继承)

    2,原型与原型链的作用

    实现了js的继承
    实现了实例的公用属性和方法

    3,显与隐关系

    var arr = [];
    arr.proto === Array.prototype

    类显示原型protype等于其创建的实例的隐式原型__proto__

    4,原型链

    在这里插入图片描述

    八,js实现继承

    1, class 的 extends方法

    class Student extends People{
       constructor(name,age,no){
         //类中继承构造函数
         super(name,age)
         ....
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2,使用原型链

    1. Stuent构造函数中继承People
    function Student(name,age,no){
      People.call(this,name,age)
      ....
    }
    
    • 1
    • 2
    • 3
    • 4

    2.继承原型链

    Student.prototype = Object.create(People.prototype)
    
    • 1
    1. 修正Student构造函数
    Stuent.prototype.constructor = Student
    
    • 1

    九,实例公用方法

    所有数组将拥有max方法

    Array.prototype.max = function(){
    	return Math.max(...this))
    }
    
    • 1
    • 2
    • 3

    所有字符串将拥有 reverse 方法

    String.prototype.reverse = function(){ 
    	return this.split("").reverse().join("")
    }
    
    • 1
    • 2
    • 3

    注意:一般不要修改默认对象上的方法,扩展也谨慎

    十,闭包

    闭包就是能够读取其他函数内部变量的函数
    闭包基本上就是一个函数内部返回一个函数

    好处

    可以读取函数内部的变量
    将变量始终保持在内存中
    可以封装对象的私有属性和私有方法

    坏处

    比较耗费内存、使用不当会造成内存溢出的问题

    十一,js变量和函数声明的提升

    在js中变量和函数的声明会提升到最顶部执行
    函数的提升高于变量的提升
    函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找
    匿名函数不会提升。

    十二,箭头函数与普通函数的区别?

    箭头函数this指向函数的上一层作用域的this
    箭头函数不能作为构造函数,没有constructor

    十三,事件流

    冒泡流:事件由最具体的元素响应然后组件冒泡到最不具体的元素(html)
    捕获流:从最不具体的元素捕获事件
    开启捕获 addEventListenter第三个参数 true
    阻止事件冒泡:e.stopPropagation()

    十四, let 与var的区别

    let 不会变量提升,var声明的变量会变量提升
    let 不能重复声明 var可重复声明
    const 声明必须赋值,值类型的值不能修改

    十五,重绘和回流

    1,重绘
    简单来说就是重新绘画,当给一个元素更换颜色、更换背景,虽然不会影响页面布局,但是颜色或背景变了,就会重新渲染页面,这就是重绘

    2,回流
    当增加或删除dom节点,或者给元素修改宽高时,会改变页面布局,那么就会重新构造dom树然后再次进行渲染,这就是回流。

    总结

    重绘不会引起dom结构和页面布局的变化,只是样式的变化,有重绘不一定有回流。
    回流则是会引起dom结构和页面布局的变化,有回流就一定有重绘。
    不管怎么说都是会影响性能。

    十六,防抖和节流

    防抖
    防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间

    节流
    节流就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率

    十七, this指向问题

    构造函数 new 函数名() this执行的 new出来对象的实例
    箭头函数的this上一层作用域的this
    对象中的this指向对象
    事件响应函数的this指向 调用者
    setTimout setInterval 里面this指向window
    call,apply,bind 响应的函数this指向第一个参数

    在这里插入图片描述

  • 相关阅读:
    sqllab第二十四关通关笔记
    Kubernetes集群故障排查—使用 crictl 对 Kubernetes 节点进行调试
    ​想短视频创业,关于短视频创作有什么建议吗?
    CEP插件-图标ICON-图标不显示-manifest.xml文件范例-CEFCommandLine命令
    Android R给自家UA工具挖坑
    2023-08-31 LeetCode每日一题(一个图中连通三元组的最小度数)
    revit\navisworks各种安装问题
    Linux Kernel入门到精通系列讲解(QEMU-虚拟化篇) 2.1 新增加一个RISC-V CPU(NARUTO-PI)
    c++学习---类和对象
    Redis如何实现持久化(AOF、RDB、混合模式)的优缺点
  • 原文地址:https://blog.csdn.net/m0_64875238/article/details/127972309