0


软通动力前端笔试面试题

文章目录

笔试题

1. 实现一个深拷贝
functiondeepcopy(obj){if(typeof obj!=='Object'||obj===null)return obj
  else{let newobj=Array.isArray(obj)?[]:{}for(let key in obj){if(obj.hasOwnProperty(key)){
        newobj[key]=deepcopy(obj[key])}}return newobj
  }}
2. 扁平化数组

指将嵌套的多维数组转换为一个一维数组

functionflattenArray(arr){let newArray=arr.reduce((acc,curr)=>{if(Array.isArray(curr)){return acc.concat(flattenArray(curr))}elsereturn  acc.concat(curr)},[])return newArray
}const nestedArray =[1,[2,[3,4],5],6];const flattenedArray =flattenArray(nestedArray);
console.log(flattenedArray);// 输出 [1, 2, 3, 4, 5, 6]
3. 数组去重
//方法1functionremoveRepeatArray(arr){let newArray=arr.reduce((acc,curr)=>{if(!acc.includes(curr))
      acc.push(curr)return acc
  },[])return newArray
}//方法2functionremoveRepeatArray(arr){return Array.from(newSet(arr))}
4. 实现一个闭包
functioncloseFunc(){let a=1functionhh(){
    a++
    console.log(a)}return hh
}const innerFunc =closeFunc();// 调用 closeFunc,得到内部函数的引用innerFunc();// 执行返回的内部函数 hh,输出 2innerFunc();// 继续执行内部函数,输出 3

一面

1. 计算一个字符在字符串中出现的次数
//方法1functioncountString(char,str){let count=0for(let i=0;i<str.length;i++){if(char===str.charAt(i))
    count++}return count
}//方法2functioncountString(char,str){const regex=newRegExp(char,'g')let arr =[]
  arr=str.match(regex)return arr.length
}const char ='a';const str ='banana';const count =countString(char, str);
console.log(count);// 输出 3
2. for of和for in 的区别
for...of

for...in

是 JavaScript 中两种不同的迭代循环语句,它们在使用上有一些区别。

  1. for...of 循环:- 用于遍历可迭代对象(例如数组、字符串、Set、Map、Generator 等)的值。- 循环体内直接访问每个元素的值,而不是索引或键。- 不适用于遍历普通对象(Plain Object)。- 语法:for(const value of iterable){// 循环体}- 示例:const arr =[1,2,3];for(const num of arr){ console.log(num);// 输出 1, 2, 3}
  2. for...in 循环:- 用于遍历普通对象(Plain Object)的可枚举属性。- 循环体内访问的是每个属性的键(属性名)。- 也可以用于遍历数组或类数组对象,但可能会出现意外结果,因为它遍历的是对象的键而不是索引。- 语法:for(const key in object){// 循环体}- 示例://遍历对象const obj ={a:1,b:2,c:3};for(const key in obj){ console.log(key);// 输出 a, b, c}//也可以遍历数组(会有问题)const arr =[8,5,9];for(const index in arr){ console.log(index);// 输出 0, 1, 2}//但是会有问题。//问题如下Array.prototype.customMethod=function(){ console.log('Custom method');};const arr =[8,5,9];for(const index in arr){ console.log(index);// 输出 0, 1, 2, "customMethod"}//解答:因为for...in 循环遍历了数组的原型链上的属性//解决Array.prototype.customMethod=function(){ console.log('Custom method');};const arr =[8,5,9];for(const index in arr){if(arr.hasOwnProperty(index))//判断是否是自身的属性,而不是原型上的属性{ console.log(index);// 输出 0, 1, 2}}

总结:

  • for...of 用于遍历可迭代对象的值。
  • for...in 用于遍历对象的可枚举属性,也可用于遍历数组的键。
  • 在处理数组时,推荐使用 for...of,而在处理对象时,推荐使用 for...in
3. let const 的区别
  1. 可变性: - let 声明的变量是可变的(mutable),意味着你可以重新赋值给这个变量。- const 声明的变量是不可变的(immutable),意味着一旦被赋值就不能再改变。
  2. 作用域: - 无论是 let 还是 const 声明的变量都具有块级作用域,它们在定义它们的块中可见,并且在该块结束后将被销毁。
  3. 重复声明: - 在同一个作用域内,let 允许你重新声明同名变量,而 const 则不允许。
  4. 初始化: - let 声明的变量可以在声明后稍后初始化。- const 声明的变量必须在声明时进行初始化,且一旦初始化后就不能再重新赋值。
  5. 全局对象属性: - 用 letconst 声明的全局变量不会成为全局对象的属性(在浏览器中是 window 对象),而用 var 声明的全局变量会成为全局对象的属性。
4. filter使用方法

是 JavaScript 数组的一个高阶函数,用于筛选数组中满足条件的元素,返回一个新的数组。

const numbers =[1,2,3,4,5,6,7,8,9,10];let evenNumbers=numbers.filter((ele,index,Arry)=>{
    console.log(ele,index,Arry)//ele 为当前元素值,index为索引,Arry为原数组return ele%2===0})
console.log(evenNumbers);
5. 数组遍历有哪些方法
  • for循环
  • for of
  • for in 需要使用hasProperty判断
  • forEach
  • map
  • reduce
  • filter
6. vue2 vue3 响应式原理分析

Vue 2 和 Vue 3 的响应式原理有所不同。下面分别对 Vue 2 和 Vue 3 的响应式原理进行简要分析。

Vue 2 的响应式原理

Vue 2 使用了基于

Object.defineProperty

的劫持(Object.defineProperty-based Observer)来实现响应式。

  1. 数据劫持:Vue 2 在组件初始化时,会对组件的 data 数据进行递归遍历,并通过 Object.defineProperty 将每个属性转化为 getter/setter。这样一来,当访问或修改这些属性时,Vue 2 就能够监听到,并触发相应的依赖追踪和更新操作。
  2. 依赖追踪:Vue 2 通过在 getter 中收集依赖,在访问属性时将依赖关系建立起来。每个属性都有一个对应的依赖收集器(Dep),用于存储依赖关系。
  3. Watcher:在模板编译过程中,Vue 2 会解析模板中的表达式,并创建对应的 Watcher。Watcher 会在初始化时触发一次属性的 getter,从而建立起属性与 Watcher 之间的关联。当属性发生变化时,会通知相关的 Watcher 进行更新。
  4. 派发更新:当属性发生变化时,会触发对应的 setter,setter 中会通知属性对应的依赖收集器(Dep)派发更新。Dep 会遍历所有相关的 Watcher,并调用 Watcher 的更新函数,进而更新视图。
Vue 3 的响应式原理

Vue 3 使用了基于 ES6 的 Proxy 对象来实现响应式。相比 Vue 2 的劫持方式,Vue 3 的响应式原理更加简洁高效。

  1. Proxy 对象:Vue 3 在组件初始化时,创建了一个根级的响应式代理对象,该对象会代理组件的 data 数据。Proxy 对象可以拦截对代理对象的访问和修改操作。
  2. 依赖追踪:Vue 3 使用了一个全新的响应式引擎,利用了 JavaScript 语言自身的特性。在访问代理对象时,会收集依赖关系,并建立起属性与依赖之间的映射关系。
  3. Reactivity API:Vue 3 提供了一组 API(如 reactiverefcomputed 等)用于创建响应式数据,这些 API 在内部会使用 Proxy 对象来实现响应式。
  4. 副作用追踪:Vue 3 使用了类似于 React Hooks 的方式,通过 effect 函数来追踪副作用。effect 函数会在组件渲染时执行,并自动追踪其中访问的响应式数据,并建立起响应式数据与副作用之间的关联。
  5. 派发更新:当响应式数据发生变化时,会自动触发更新,重新执行相关的副作用函数,同时通知组件进行局部更新,以保持视图与数据的同步。

总的来说,Vue 2 和 Vue 3 都使用了不同的技术手段来实现响应式。Vue 2 使用了

Object.defineProperty

进行数据劫持,而 Vue 3 则利用了 ES6 的 Proxy 对象来实现响应式,使得代码更加简洁高效。

7. vue3升级优化分析

Vue 3 相对于 Vue 2 在性能和开发体验上都有一系列的优化和改进。以下是一些主要的升级优化分析:

  1. 更好的性能: - 虚拟 DOM 重写:Vue 3 对虚拟 DOM 进行了重写,使其更加高效。新的虚拟 DOM 实现减少了许多不必要的操作,并提高了渲染性能。- 静态提升:Vue 3 在编译阶段能够识别出静态节点,并将其提升为常量,减少了运行时的开销。- Tree-shaking 支持:Vue 3 支持更好的 Tree-shaking,使得打包工具能够更好地优化代码,减少打包体积。
  2. 更小的体积: - 模块化构建:Vue 3 的代码更加模块化,可以按需加载,从而减少了整体的体积。- Composition API 的模块化引入:Vue 3 的 Composition API 具有模块化的特性,使得开发者可以更加灵活地组织代码,从而减少了代码量。
  3. 更好的 TypeScript 支持: - 全面支持 TypeScript:Vue 3 的代码基本上是用 TypeScript 编写的,因此对 TypeScript 的支持更加全面和友好。- 更好的类型推断:Vue 3 在编译时会生成更加准确的类型定义,使得开发时能够获得更好的类型推断和代码提示。
  4. 更灵活的组件设计: - Composition API:Vue 3 引入了 Composition API,使得组件的逻辑可以更加灵活地组织,提高了代码的可维护性和可复用性。- Teleport 和 Suspense:Vue 3 新增了 Teleport 和 Suspense 这两个特性,使得开发者能够更灵活地控制组件的渲染位置和加载状态。
  5. 更好的开发体验: - 更快的开发速度:通过 Composition API 和 TypeScript 的支持,使得开发者能够更快地编写和调试代码。- 更好的错误提示:Vue 3 对错误提示进行了改进,使得开发者能够更容易地定位和解决问题。

总的来说,Vue 3 在性能、体积、开发体验和灵活性等方面都有明显的优化和改进,是一个更加成熟和强大的框架。因此,对于使用 Vue 的项目来说,考虑升级到 Vue 3 是一个非常值得的选择。


本文转载自: https://blog.csdn.net/qingqing37/article/details/137557092
版权归原作者 在田野的田田 所有, 如有侵权,请联系我们删除。

“软通动力前端笔试面试题”的评论:

还没有评论