前端高频面试题 Day02

面试题

var 和 let const 的区别

  • var 是 ES5 及之前的语法,let const 是 ES6 语法
  • var 和 let 是变量,可修改;const 是常量,不可修改
  • var 有变量提升,let const 没有
  • var 没有块级作用域,let const 有 (ES6 语法有块级作用域)
// var 变量提升
console.log('a', a)
var a = 100// let 没有变量提升
console.log('b', b)
let b = 200
// var 没有块级作用域
for (var i = 0; i < 10; i++) {var j = 1 + i
}
console.log(i, j)// let 有块级作用域
for (let x = 0; x < 10; x++) {let y = 1 + x
}
console.log(x, y)

typeof 有哪些返回类型?

// 判断所有值类型
let a
console.log(a) // 'undefined'
const str = 'abc'
typeof str  // 'string'
const n = 100
typeof n // 'number'
const b = true
typeof b // 'boolean'
const s = Symbol('s')
typeof s // 'symbol'

列举强制类型转换和隐式类型转换

  • 强制 parseInt parseFloat
  • 隐式 if==+ 拼接字符串

手写深度比较,如 lodash isEqual

// 实现如下效果
const obj1 = {a: 10, b: { x: 100, y: 200 }}
const obj2 = {a: 10, b: { x: 100, y: 200 }}
isEqual(obj1, obj2) === true
// 判断是否是 object
function isObject(obj) {return typeof obj === 'object' && obj !== null
}
// 全相等
function isEqual(obj1, obj2) {if (!isObject(obj1) || !isObject(obj2)) {// 值类型,不是对象或数组(注意,equal 时一般不会有函数,这里忽略)return obj1 === obj2}if (obj1 === obj2) {// 两个引用类型全相等(同一个地址)return true}// 两个都是引用类型,不全相等// 1. 先取出 obje2 obj2 的 keys,比较个数const obj1Keys = Object.keys(obj1)const obj2Keys = Object.keys(obj2)if (obj1Keys.length !== obj2Keys.length) {// keys 个数不相等,则不是全等return false}// 2. 以 obj1 为基准,和 obj2 依次递归比较for (let key in obj1) {// 递归比较const res = isEqual(obj1[key], obj2[key])if (!res) {// 遇到一个不相等的,则直接返回 falsereturn false}}// 3. 都相等,则返回 truereturn true
}

split()join() 的区别

'1-2-3'.split('-')
[1,2,3].join('-')

数组的 pop push unshift shift 分别做什么

注意以下几点

  • 函数作用是什么?
  • 返回值是什么?
  • 对原数组是否造成影响?
  • 如何对原数组不造成影响?concat slice map filter

【扩展】数组 API 的纯函数和非纯函数

纯函数 —— 1. 不改变来源的数组; 2. 返回一个数组

  • concat
  • map
  • filter
  • slice
const arr = [100, 200, 300]
const arr1 = arr.concat([400, 500])
const arr2 = arr.map(num => num * 10)
const arr3 = arr.filter(num => num > 100)
const arr4 = arr.slice(-1)

非纯函数

情况1,改变了原数组

  • push
  • reverse
  • sort
  • splice

情况2,未返回数组

  • push
  • forEach
  • reduce
  • some

数组 slice 和 splice 的区别?

slice - 切片;splice - 剪接;

// slice()
const arr1 = [10, 20, 30, 40, 50]
const arr2 = arr1.slice() // arr2 和 arr1 不是一个地址,纯函数,重要!!!// arr.slice(start, end)
const arr1 = [10, 20, 30, 40, 50]
const arr2 = arr1.slice(1, 4) // [20, 30, 40]// arr.slice(start)
const arr1 = [10, 20, 30, 40, 50]
const arr2 = arr1.slice(2) // [30, 40, 50]// 负值
const arr1 = [10, 20, 30, 40, 50]
const arr2 = arr1.slice(-2) // [40, 50]
// arr.splice(index, howmany, item1, ....., itemX)
const arr1 = [10, 20, 30, 40, 50]
const arr2 = arr1.splice(1, 2, 'a', 'b', 'c') // [20, 30]
// arr1 会被修改,不是纯函数,即有副作用

[10, 20, 30].map(parseInt) 的结果是什么?

// 拆解开就是
[10, 20, 30].map((num, index) => {return parseInt(num, index)// parseInt 第二个参数是进制// 如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。// 如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN
})
// 可以对比
[10, 20, 30].map((num, index) => {return parseInt(num, 10)
})

ajax 请求中 get 和 post 的区别

  • get 一般用于查询操作,post 一般用于提交操作
  • get 参数在 url 上,post 在请求体内
  • 安全性:post 请求易于防止 CSRF

(post 代码演示:网页,postname)

call 和 apply 的区别

  • fn.call(this, p1, p2, p3)
  • fn.apply(this, arguments)

事件委托(代理)是什么

const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', e => {e.stopPropagation() // 注释掉这一行,来体会事件冒泡alert('激活')
})
bindEvent(body, 'click', e => {alert('取消')
})

闭包是什么,有什么特性,对页面有什么影响

知识点回顾

  • 回归作用域和自由变量
  • 闭包的应用场景:函数作为参数被传入,函数作为返回值被返回
  • 关键点:自由变量的查找,要在函数定义的地方,而不是执行的地方

对页面的影响

  • 变量内存得不到释放,可能会造成内存积累(不一定是泄露)
// 自由变量示例 —— 内存会被释放
let a = 0
function fn1() {let a1 = 100function fn2() {let a2 = 200function fn3() {let a3 = 300return a + a1 + a2 + a3}fn3()}fn2()
}
fn1()
// 闭包 函数作为返回值 —— 内存不会被释放
function create() {let a = 100return function () {console.log(a)}
}
let fn = create()
let a = 200
fn() // 100// 闭包 函数作为参数 —— 内存不会被释放
function print(fn) {let a = 200fn()
}
let a = 100
function fn() {console.log(a)
}
print(fn) // 100

如何阻止事件冒泡和默认行为

event.stopPropagation()
event.preventDefault()

添加 删除 替换 插入 移动 DOM 节点的方法

(粘贴一下代码片段,作为回顾)

怎样减少 DOM 操作?

  • 缓存 DOM 查询结果
  • 多次操作,合并到一次插入

(粘贴一下代码片段,作为回顾)

解释 jsonp 的原理,以及为什么不是真正的 ajax

  • 浏览器的同源策略,什么是跨域?
  • 哪些 html 标签能绕过跨域?
  • jsonp 原理

document load 和 document ready 的区别

window.addEventListener('load', function () {// 页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded', function () {// DOM 渲染完即可执行,此时图片、视频还可能没有加载完
})

===== 的不同

  • == 会尝试进行类型转换
  • === 严格相等

函数声明与函数表达式的区别?

const res = sum(10, 20)
console.log(res) // 30// 函数声明
function sum(x, y) {return x + y
}
const res = sum(100, 200)
console.log(res) // 报错!!!// 函数表达式
const sum = function(x, y) {return x + y
}

new Object()Object.create() 的区别

示例一

const obj1 = {a: 10,b: 20,sum() {return this.a + this.b}
}
const obj2 = new Object({a: 10,b: 20,sum() {return this.a + this.b}
})
const obj3 = Object.create({a: 10,b: 20,sum() {return this.a + this.b}
})
// 分别打印看结构

示例二

const obj1 = {a: 10,b: 20,sum() {return this.a + this.b}
}
const obj2 = new Object(obj1)
console.log(obj1 === obj2) // true
const obj3 = Object.create(obj1)
console.log(obj1 === obj3) // falseconst obj4 = Object.create(obj1)
console.log(obj3 === obj4) // false// 然后修改 obj1 ,看 obj2 obj3 和 obj4
obj1.printA = function () {console.log(this.a)
}

对作用域上下文和 this 的理解,场景题

const User = {count: 1,getCount: function() {return this.count}
}
console.log(User.getCount()) // what?
const func = User.getCount
console.log( func() ) // what?

对作用域和自由变量的理解,场景题

let i
for(i = 1; i <= 3; i++) {setTimeout(function(){console.log(i)}, 0)
}
// what?

判断字符串以字母开头,后面可以是数字,下划线,字母,长度为 6-30

const reg = /^[a-zA-Z]\w{5,29}$/

  • 查看正则表达式规则 https://www.runoob.com/regexp/regexp-syntax.html
  • 查看常见正则表达式
/\d{6}/ // 邮政编码
/^[a-z]+$/ // 小写英文字母
/^[A-Za-z]+$/ // 英文字母
/^\d{4}-\d{1,2}-\d{1,2}$/ // 日期格式
/^[a-zA-Z]\w{5,17}$/ // 用户名(字母开头,字母数字下划线,5-17位)
/\d+\.\d+\.\d+\.\d+/ // 简单的 IP 地址格式

以下代码,分别 alert 出什么?

let a = 100
function test() {  alert(a)a = 10alert(a)
}
test()
alert(a)
// what?

手写 trim 函数,保证浏览器兼容性

String.prototype.trim= function (){return this.replace(/^\s+/,"").replace(/\s+$/,"")
}

知识点:原型,this,正则

如何获取多个数值中的最大值?

Math.max(10, 30, 20, 40)
// 以及 Math.min
function max() {const nums = Array.prototype.slice.call(arguments) // 变为数组let max = 0nums.forEach(n => {if (n > max) {max = n}})return max
}

如何用 JS 实现继承?

class 代码

程序中捕获异常的方法

try {// todo
} catch (ex) {console.error(ex) // 手动捕获 catch
} finally {// todo
}
// 自动捕获 catch(但对跨域的 js 如 CDN 的,不会有详细的报错信息)
window.onerror = function (message, source, lineNom, colNom, error) {
}

什么是 JSON ?

首先,json 是一种数据格式标准,本质是一段字符串,独立于任何语言和平台。注意,json 中的字符串都必须用双引号。

{"name": "张三","info": {"single": true,"age": 30,"city": "北京"},"like": ["篮球", "音乐"]
}

其次,JSON 是 js 中一个内置的全局变量,有 JSON.parseJSON.stringify 两个 API 。

获取当前页面 url 参数

自己实现

// const url = 'https://www.xxx.com/path/index.html?a=100&b=200&c=300#anchor'
function query(name) {const search = location.search.substr(1) // 去掉前面的 `?`const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i')const res = search.match(reg)if (res === null) {return null}return decodeURIComponent(res[2])
}
console.log( query('a') )
console.log( query('c') )

新的 API URLSearchParams

const pList = new URLSearchParams(location.search)
pList.get('a')

将 url 参数解析为 JS 对象?

自己编写

function queryToObj() {const res = {}const search = location.search.substr(1) // 去掉前面的 `?`search.split('&').forEach(paramStr => {const arr = paramStr.split('=')const key = arr[0]const val = arr[1]res[key] = val})return res
}

新的 API URLSearchParams

function queryToObj() {const res = {}const pList = new URLSearchParams(location.search)pList.forEach((val, key) => {res[key] = val})return res
}

实现数组 flatern ,考虑多层级


function flat(arr) {// 验证 arr 中,还有没有深层数组,如 [1, [2, 3], 4]const isDeep = arr.some(item => item instanceof Array)if (!isDeep) {return arr // 没有深层的,则返回}// 多深层的,则 concat 拼接const res = Array.prototype.concat.apply([], arr) // 回归上文,apply 和 call 的区别return flat(res) // 递归调用,考虑多层
}
flat([[1,2], 3, [4,5, [6,7, [8, 9, [10, 11]]]]])

数组去重

要考虑:

  • 顺序是否一致?
  • 时间复杂度

ES5 语法手写。

// 写法一
function unique(arr) {const obj = {}arr.forEach(item => {obj[item] = 1 // 用 Object ,去重计算高效,但顺序不能保证。以及,非字符串会被转换为字符串!!!})return Object.keys(obj)
}
unique([30, 10, 20, 30, 40, 10])
// 写法二
function unique(arr) {const res = []arr.forEach(item => {if (res.indexOf(item) < 0) { // 用数组,每次都得判断是否重复(低效),但能保证顺序res.push(item)}})return res
}
unique([30, 10, 20, 30, 40, 10])

用 ES6 Set

// 数组去重
function unique(arr) {const set = new Set(arr)return [...set]
}
unique([30, 10, 20, 30, 40, 10])

手写深拷贝

粘贴代码

【注意】Object.assign 不是深拷贝,可以顺带讲一下用法

  • Object.assign(obj1, {...})
  • const obj2 = Object.assign({}, obj1, {...})

介绍一下 RAF requestAnimationFrame

想用 JS 去实现动画,老旧的方式是用 setTimeout 实时刷新,但这样效率非常低,而且可能会出现卡顿。

  • 想要动画流畅,更新频率是 60帧/s ,即每 16.6ms 更新一次试图。太慢了,肉眼会感觉卡顿,太快了肉眼也感觉不到,资源浪费。
  • 用 setTimeout 需要自己控制这个频率,而 requestAnimationFrame 不用自己控制,浏览器会自动控制
  • 在后台标签或者隐藏的<iframe>中,setTimeout 依然会执行,而 requestAnimationFrame 会自动暂停,节省计算资源

(代码演示)

对前端性能优化有什么了解?一般都通过那几个方面去优化的?

原则

  • 多使用内存、缓存或者其他方法
  • 减少 CPU 计算、较少网络

方向

  • 加载页面和静态资源
  • 页面渲染

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/40332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb-DAO设计模式

目录 DAO设计模式 1.认识DAO 2.DAO各部分的详解 3.DAO设计模式流程 DAO设计模式 1.认识DAO DAO(Data Acess Object 数据库访问对象)的主要功能是操作数据库&#xff0c;所以DAO在标准开发架构中数据数据层&#xff0c;以下是标准开发的架构 客户层&#xff1a;目前使用B/…

vue中style scoped属性的作用

一、为什么要给style 节点加 scoped 属性&#xff08;vue&#xff09; 1、作用&#xff1a;当style标签里面有scoped属性时&#xff0c;它的css只作用于当前组建的元素。在单页面项目中可以使组件之间互不污染&#xff0c;实现模块化&#xff08;实现组件的私有化&#xff0c;不…

Ubuntu安装mysql5.7

目录 1. 更新系统软件包2. 安装MySQL 5.73. 启动MySQL 服务4. 设置MySQL root 密码5. 验证MySQL 安装6. 启用远程访问7. 创建新用户8. 为新用户授予权限9. mysql命令 以Ubuntu 18.04系统为例&#xff0c;安装MySQL 5.7。操作步骤如下&#xff1a; 1. 更新系统软件包 sudo apt…

Openai中的tokens怎么估计

大规模语言模型&#xff08;LLM&#xff09;的出现给自然语言处理领域带来了变革的可能性&#xff0c;Openai开放了chatgpt的API&#xff0c;方便了开发人员使用LLM的推理能力&#xff0c;注册时赠送5美元的使用额度&#xff0c;有效期3个月。 如果想便捷的使用chatgpt的API&a…

介绍 TensorFlow 的基本概念和使用场景

TensorFlow 是一种开源的机器学习框架&#xff0c;由 Google 开发。它是用来构建和训练机器学习模型的强大工具&#xff0c;支持很多种不同类型的机器学习算法&#xff0c;并使用数据流图来表示计算过程。 TensorFlow 的核心是张量 (Tensor) 和计算图 (Graph)。 张量 (Tensor)…

OpenCV之薄板样条插值(ThinPlateSpline)

官方文档&#xff1a;OpenCV: cv::ThinPlateSplineShapeTransformer Class Reference 使用方法&#xff1a; 头文件&#xff1a;#include <opencv2/shape/shape_transformer.hpp> &#xff08;1&#xff09;点匹配 一般根据有多少个样本&#xff08;或者点&#xff09;…

6.2 Spring Boot整合MyBatis

1、基于Spring BootMyBatis的学生信息系统的设计与实现案例 基于Spring BootMyBatis实现学生信息的新增、修改、删除、查询功能&#xff0c;并实现MySQL数据库的操作。 MySQL数据库创建学生表&#xff08;t_student&#xff09;&#xff0c;有主键、姓名、年龄、性别、出生日…

npm如何设置淘宝的镜像源模式

1. 查看当前npm的下载源 npm config get registry2. 全局配置npm使用淘宝镜像作为默认下载源 npm config set registry https://registry.npm.taobao.org --global3. 安装依赖包 npm install <package-name> 添加到devDependencies字段中&#xff1a; npm install &l…

Jmeter 二次开发 函数助手 AES加解密

Jmeter 二次开发 函数助手 AES加解密 1. 环境准备2. 关键技术说明2.1 离线导包2.2 示例代码 3. 代码包4. 结果演示 1. 环境准备 IDE &#xff1a;IntelliJ IDEA 2021.1.1 x64JAVA环境 &#xff1a;jdk1.8.0_251离线导包&#xff1a;导入Jmeter安装目录下lib/ext下的ApacheJmet…

Java课题笔记~ SpringMVC的四种跳转方式

默认的跳转是请求转发&#xff0c;直接跳转到jsp页面展示 还可以使用框架提供的关键字redirect&#xff0c;进行一个重定向操作&#xff0c;包括重定向页面和重定向action&#xff0c;使用框架提供的关键字forward&#xff0c;进行服务器内部转发操作&#xff0c;包括转发页面…

Martin_DHCP_V3.0 (DHCP自动化泛洪攻击GUI)

Github>https://github.com/MartinxMax/Martin_DHCP_V3.0 首页 Martin_DHCP_V3.0 自动化DHCP洪泛攻击 Martin_DHCP_V3.0 使用方法 安装三方库 #python3 1.RunMe_Install_Packet.py 攻击路由器 #python3 Martin_DHCP_Attack.py 填写网卡 填写攻击次数 开始运行

《Go 语言第一课》课程学习笔记(二)

初窥门径&#xff1a;一个 Go 程序的结构是怎样的&#xff1f; 创建“hello&#xff0c;world”示例程序 在 Go 语言中编写一个可以打印出“hello&#xff0c;world”的示例程序&#xff0c;我们只需要简单两步&#xff0c;一是创建文件夹&#xff0c;二是开始编写和运行。通…

高光谱 | 矿物识别和分类标签数据制作、农作物病虫害数据分类、土壤有机质含量回归与制图、木材含水量评估和制图

本课程提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 本课程涵盖高光谱遥感的基础、方法和实践。基础篇以学员为中心&#xff0c;用通俗易懂的语言解释高光谱的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。方法篇结合Python编程工具&#xff0c;…

阿里云服务器部署RabbitMQ流程

阿里云百科分享使用阿里云服务器部署RabbitMQ流程&#xff0c;RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;用于在分布式系统中存储转发消息&#xff0c;有良好的易用性、扩展性和高可用性。本文介绍如何通过ECS实例部署Rabbi…

CentOS系统环境搭建(四)——Centos7安装Java

centos系统环境搭建专栏&#x1f517;点击跳转 Centos7安装Java 查看云端yum库中目前支持安装的jdk软件包 yum search java|grep jdk选择JDK版本&#xff0c;并安装 yum install -y java-1.8.0-openjdk检查是否安装成功 java -version查看JDK的安装目录 find / -name jav…

【Java面试】redis雪崩、穿透和击穿详解

一 Redis雪崩、穿透和击穿 1. Redis雪崩&#xff1a; Redis雪崩是指在某一时刻&#xff0c;缓存中大量的缓存数据同时失效或过期&#xff0c;导致大量的请求直接打到后端数据库&#xff0c;导致数据库负载剧增&#xff0c;引发性能问题甚至崩溃。这通常是因为缓存数据的过期时…

机器学习笔记:李宏毅 stable diffusion

1 基本框架 ①&#xff1a;文字变成向量 ②&#xff1a;喂入噪声文字encoder&#xff0c;产生中间产物 ③&#xff1a;decoder 还原图片 2 text encoder 这张图越往右下表示效果越好&#xff0c;可以看到text encoder尺寸越大&#xff0c;对后续生成图片的增益越多 3 评价图…

公园游玩必备!新零售模式如何吸引更多游客

随着科技的不断演进&#xff0c;新零售模式正以前所未有的速度改变着我们的购物方式和消费体验。其中&#xff0c;自动售货机作为新零售模式的重要组成部分&#xff0c;以其智能化、便捷性和多样性的特点&#xff0c;正逐渐成为城市中熠熠生辉的一道风景线。 从24小时不间断的运…

LeetCode Top100 Liked 题单(序号34~51)

​34. Find First and Last Position of Element in Sorted Array ​ 题意&#xff1a;找到非递减序列中目标的开头和结尾 我的思路 用二分法把每一个数字都找到&#xff0c;最后返回首尾两个数 代码 Runtime12 ms Beats 33.23% Memory14 MB Beats 5.16% class Solution {…

前端练手小项目--自定义时间(html+css+js)

自定义时间 写文章的因 关于要写这篇文章的原因 是记录在工作上遇到的困难需求&#xff0c;是希望能给大家提供一些解决问题的思路 接下来我描述这个需求的多样性&#xff0c;难点在哪。 勾选勾选框开始时间与结束时间默认显示昨天与今天。取消勾选框开始时间与结束时间清空。…