征服世界的卡比兽
发布于 2023-12-09 / 428 阅读 / 0 评论 / 0 点赞

前端面试题库

前端面试题库

link 和 @import的区别是什么?

  1. link是xhtml标签,无兼容性问题,@import是css2.1提出的,低版本浏览器不支持,只有ie5以上才支持
  2. link能加载css javascript @import只能加载css
  3. link链接的内容是和html页面同步加载的,@import需要等到页面全部加载完成之后才能加载。
  4. link引入的样式权重大于@import引入的样式。

几种常见浏览器,及其内核分别是什么?

现在国内常见的浏览器有:IE、Firefox、QQ浏览器、Safari、Opera、GoogleChrome、百度浏览器、搜狗浏览器、猎豹浏览器、360浏览器、UC浏览器、遨游浏览器、世界之窗浏览器等。但目前最为主流浏览器有五大款,分别是IE、Firefox、GoogleChrome、Safari、Opera。

  1. IE浏览器内核:Trident内核,也是俗称的IE内核;
  2. Chrome浏览器内核:统称为Chromium内核或Chrome内核,以前是Webkit内核,现在是Blink内核;
  3. Firefox浏览器内核:Gecko内核,俗称Firefox内核;
  4. Safari浏览器内核:Webkit内核;
  5. Opera浏览器内核:最初是自己的Presto内核,后来是Webkit,现在是Blink内核;
  6. 360浏览器、猎豹浏览器内核:IE+Chrome双内核;
  7. 搜狗、遨游、QQ浏览器内核:Trident(兼容模式)+Webkit(高速模式);
  8. 2345浏览器内核:以前是IE内核,现在也是IE+Chrome双内核;

请描述一下cookies、sessionStorage和localStorage的区别?

cookie、sessionStorage、localStorage的相同点是都存储在客户端,不同点分别表现在存储大小、有效时间、数据与服务器的交互方式

1. 存储大小

  • cookie数据大小不能超过4k。
  • sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

2. 有效时间

  • localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
  • sessionStorage 数据在当前浏览器窗口关闭后自动删除。
  • cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

3. 数据与服务器之间的交互方式

  • cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
  • sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

new操作符具体干了什么呢?

function Func(){
}
let func= new Func();

1. 创建了⼀个空对象,作为要返回的实例对象

let obj = new Object();

2. 将空对象的原型 proto 指向构造函数的 prototype 属性

obj.__proto__ = Func.prototype;

把 obj 的proto 指向构造函数Func的原型对象 prototype,此时便建立了 obj 对象的原型链:
obj->Func.prototype->Object.prototype->null

3. 以指定构造函数的 this 为新创建的对象的⽅式调⽤构造函

let result = Func.call(obj);

让Func中的this指向obj,并执行Func的函数体。

4. 判断构造函数返回值类型返回对象

if (typeof(result) == "object"){
  func=result;
}
else{
    func=obj;
}

判断Func的返回值类型:
如果无返回值 或者 返回一个非对象值,则将 obj 作为新对象返回;否则会将 result 作为新对象返回。

js延迟加载的方式有哪些?

  1. 在script标签上,设置defer属性,可以达到异步加载js文件,延迟执行js脚本文件的目的
  2. 在script标签上,设置async属性,可以达到异步加载js文件的目的。
  3. 动态创建script标签,当页面的全部内容加载完毕后,在执行创建挂载

什么是闭包?使用场景有哪些?

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

function fn1() {
    var name = 'Fuleny'
    return function() {
        console.log(name)
    }
}

var fn2 = fn1()
fn2()

在上述代码中,闭包指的就是 return function() { console.log(name) }这个函数。

这个函数在fn1函数作用域内部,所以能访问到函数内部的变量name,fn1函数内部的返回值由全局作用域下的变量fn2接收,调用fn2就可以实现在全局变量下访问局部变量中的变量的值。

常见场景:

  1. 用闭包模拟私有方法
  2. 回调
  3. 列表循环点击

js中null 和 undefined 有什么区别?

javascript权威指南:null 和 undefined 都表示 “值的空缺”,你可以认为 undefined 是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。

javascript高级程序设计:在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。nunll值则是表示空对象指针

undefined

undefined代表未定义,也就是不存在的意思。也可以换个角度,就是应该有值,但是还没赋值,连null值都没有赋予。

null

null则代表有值,是存在的,但是为空值。空值不是不存在,而是有一个叫做 空值的值。在语言层面,null是object,是一种特殊的 空对象。如果把一个变量赋予null,则该变量原先指向的对象可以被GC回收,释放内存空间。当然也可以认为null是null类型,这不影响实际的意义。

Doctype的作用是什么?严格模式与混杂模式如何区分?它们有什么意义?

作用: DOCTYPE是document type(文档类型的)的简写。用来说明你用的是XHTML获HTML是什么版本。

如何区分: 浏览器解析时到底使⽤严格模式还是混杂模式,与⽹页中的 DTD 直接相关。不声明 DOCTYPE 的话,浏览器会以 Quicks Mode(混杂模式) 渲染页面

严格模式:⼜称标准模式,是指浏览器按照 W3C 标准解析代码。
混杂模式:⼜称怪异模式或兼容模式,是指浏览器⽤⾃⼰的⽅式解析代码。

意义: 严格模式与混杂模式存在的意义与其来源密切相关,如果说只存在严格模式,那么许多旧⽹站必然受到影响,如果只存在混杂模式,那么会回到当时浏览器⼤战时的混乱,每个浏览器都有⾃⼰的解析模式。

谈谈如何优化网页运行性能?

  1. 减少 HTTP 请求数
  2. 减少 DNS 查询
  3. 使用 CDN
  4. 避免重定向
  5. 图片懒加载
  6. 减少 DOM 元素数量
  7. 减少 DOM 操作
  8. 使用外部 JavaScript 和 CSS
  9. 压缩 JavaScript、CSS、字体、图片等
  10. 优化 CSS Sprite
  11. 使用 iconfont
  12. 多域名分发划分内容到不同域名
  13. 尽量减少 iframe 使用
  14. 避免图片 src 为空
  15. 把样式表放在 link 中
  16. 把 JavaScript 放在页面底部

js数据类型有什么?

基本数据类型:

Number、String、Boolean、Null、Undefined、Symbol、bigInt

引用数据类型:

object、Array、Date、Function、RegExp

js中数组(array)有哪些方法?

  • map : 遍历数组,返回回调返回值组成的新数组
  • forEach : 无法 break ,可以用 try/catch 中 throw new Error 来停止filter : 过滤
  • some : 有一项返回 true ,则整体为 true
  • every : 有一项返回 false ,则整体为 false
  • join : 通过指定连接符生成字符串
  • push / pop : 末尾推入和弹出,改变原数组, 返回推入/弹出项
  • unshift / shift : 头部推入和弹出,改变原数组,返回操作项
  • sort(fn) / reverse : 排序与反转,改变原数组
  • concat : 连接数组,不影响原数组, 浅拷贝
  • slice(start, end) : 返回截断后的新数组,不改变原数组
  • splice(start,number,value…): 返回删除元素组成的数组,value 为插入项,改变原数组
  • indexOf / lastIndexOf(value, fromIndex) : 查找数组项,返回对应的下标
  • reduce / reduceRight(fn(prev, cur) ,defaultPrev) : 两两执行,prev 为上次化简函数的return 值,cur 为当前值(从第二项开始)

什么是同源策略?

同源指的是域名、协议、端口号相同

如何解决跨域?

  • jsonp跨域
  • document.domain + iframe 跨域
  • nodejs中间件代理跨域
  • 后端在头部信息里面设置安全域名

什么是作用域链?

作用域链可以理解为一组对象列表,包含 父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数

js变量和函数声明的提升

在js中变量和函数的声明会提升到最顶部执行

函数的提升高于变量的提升

函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找。

匿名函数不会提升。

什么是原型、原型链、继承?

所有的函数都有prototype属性(原型)
所有的对象都有proto属性
在Javascript中,每个函数都有一个原型属性prototype指向自身的原型,而由这个函数创建的对象也有一个proto属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个proto指向自己的原型,这样逐层深入直到Object对象的原型,这样就形成了原型链。

JS垃圾回收机制是怎样的?

1.概述

js的垃圾回收机制是为了防止内存泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存。
在JS中,JS的执行环境会负责管理代码执行过程中使用的内存。

2.变量的生命周期

当一个变量的生命周期结束之后,它所指向的内存就会被释放。js有两种变量,局部变量和全局变量,局部变量是在他当前的函数中产生作用,当该函数结束之后,该变量内存会被释放,全局变量的话会一直存在,直到浏览器关闭为止。

3.js垃圾回收方式

有两种方式: 标记清除、引用计数

标记清除:大部分浏览器使用这种垃圾回收,当变量进入执行环境(声明变量)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其再度标记,随之进行删除。

引用计数:这种方式常常会引起内存的泄露,主要存在于低版本的浏览器。它的机制就是跟踪某一个值得引用次数,当声明一个变量并且将一个引用类型赋值给变量得时候引用次数加1,当这个变量指向其他一个时引用次数减1,当为0时出发回收机制进行回收。

逐进增强和优雅降级

逐进增强
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高版本浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容

什么是单线程,和异步的关系?

单线程 :只有一个线程,只能做一件事

原因 : 避免 DOM 渲染的冲突
浏览器需要渲染 DOM
JS 可以修改 DOM 结构
JS 执行的时候,浏览器 DOM 渲染会暂停
两段 JS 也不能同时执行(都修改 DOM 就冲突了)
webworker 支持多线程,但是不能访问 DOM

解决方案 :异步

说说异步编程的实现方式?

回调函数

  • 优点:简单、容易理解
  • 缺点:不利于维护、代码耦合高

事件监听

  • 优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
  • 缺点:事件驱动型,流程不够清晰

发布/订阅(观察者模式)
类似于事件监听,但是可以通过‘消息中心’,了解现在有多少发布者,多少订阅者

Promise 对象

  • 优点:可以利用 then 方法,进行链式写法;可以书写错误时的回调函数
  • 缺点:编写和理解,相对比较难

Generator 函数

  • 优点:函数体内外的数据交换、错误处理机制
  • 缺点:流程管理不方便

async 函数

  • 优点:内置执行器、更好的语义、更广的适用性、返回的是 Promise、结构清晰
  • 缺点:错误处理机制

js数组和对象的遍历方式

  1. for in
  2. for
  3. forEach
  4. for-of

数组去重有什么方法?

// 使用 `Set`
const newArr = Array.from(new Set([1, 2, 3, 4, 4, 4, 1]));

// 使用 `indexOf`
const unique = function (arr) {
  const newArray = [];
  arr.forEach((item) => {
    if (newArray.indexOf(item) === -1) {
      newArray.push(item);
    }
  });
  return newArray;
};

// 使用 `sort`
const unique = function (data) {
  const newArray = [];
  let arr = data;
  arr.sort();
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] !== arr[i + 1]) {
      newArray.push(arr[i]);
    }
  }
  return newArray;
};

如何实现节流函数?

function throttle(fn, delay) {
  let canUse = true;
  return function () {
    if (canUse) {
      canUse = false;
      fn.call();
      setTimeout(() => {
        canUse = true;
      }, delay);
    }
  };
}

const throttled = throttle(() => console.log("throttled"), 1000);

如何实现防抖函数?

function debounce(fn, delay) {
  let timerId = null;
  return function () {
    const context = this;
    if (timerId) clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(context, arguments);
    }, delay);
  };
}
const debounced = debounce(() => console.log("debounced"), 3000);

vue3和vue2的钩子函数有什么区别?

vue2     --------------- vue3
beforeCreate        ->   setup()
Created             ->   setup()
beforeMount         ->   onBeforeMount
mounted             ->   onMounted
beforeUpdate        ->   onBeforeUpdate
updated             ->   onUpdated
beforeDestroyed     ->   onBeforeUnmount
destroyed           ->   onUnmounted
activated           ->   onActivated
deactivated         ->   onDeactivated

vue更新数组时触发视图更新的方法

push();
pop();
shift();
unshift();
splice();
sort();
reverse()

vue优点

  1. 轻量级
  2. 速度快
  3. 简单易学
  4. 低耦合
  5. 可重用性
  6. 独立开发
  7. 文档齐全,且文档为中文文档

v-if和v-show有什么区别?

v-show隐藏是为该元素添加css display:none, v-if显示隐藏是将dom元素整个添加删除。

vue组件的通信方式

  • props/$emit 父子组件通信
    父->子props,子->父 $on$emit 获取父子组件实例 parentchildren Ref 获取实例的方式调用组件的属性或者方法 父->子孙 Provideinject 官方不推荐使用,但是写组件库时很常用

  • $emit/$on 自定义事件 兄弟组件通信
    Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue() 自定义事件

  • vuex 跨级组件通信
    Vuex$attrs$listeners Provideinject

var && let && const的区别

ES6之前创建变量用的是var,之后创建变量用的是let/const
三者区别:

  1. var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
    let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
    const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,且不能修改。
  2. var可以先使用,后声明,因为存在变量提升;let必须先声明后使用。
  3. var是允许在相同作用域内重复声明同一个变量的,而let与const不允许这一现象。
  4. 在全局上下文中,基于let声明的全局变量和全局对象GO(window)没有任何关系 ;
    var声明的变量会和GO有映射关系;
  5. 会产生暂时性死区:

    暂时性死区是浏览器的bug:检测一个未被声明的变量类型时,不会报错,会返回undefined
    如:console.log(typeof a) //undefined
    而:console.log(typeof a)//未声明之前不能使用
    let a

  6. let /const/function会把当前所在的大括号(除函数之外)作为一个全新的块级上下文,应用这个机制,在开发项目的时候,遇到循环事件绑定等类似的需求,无需再自己构建闭包来存储,只要基于let的块作用特征即可解决