新 API

最新的 url 参数获取的 API?

URLSearchParams

// 有如下一个url: http://localhost?a=1&b=2

function getUrlParam(name) {
let paramStr = location.search.substr(1)
let params = new URLSearchParams(paramStr)
return params.get(name)
} console.log(getUrlParam('a')) // 1

数组

实现数组去重?

现在有如下一个数组:

let arr = [1, 1, 'true', 'true', true, true, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}]
  • 使用 ES6 的 Set 方法

利用 Set 数据类型的特性,集合内部不会有重复的元素 不能过滤对象

Array.from(new Set(arr));

// 等于

[...new Set(arr)];
  • 使用对象键值唯一的特性

不能过滤对象

function unique(arr) {
let obj = {}
return arr.filter((item) => {
let key = typeof item + item
return obj.hasOwnProperty(key) ? false : (obj[key] = true)
})
}

因为对象的 key 是 string 类型,无论你传入什么他都会解析成字符串,所以就导致了数字 1 和字符串 1,在对象中的 key 是相同的。 所以会把它们当成相同的数据过滤掉,所以可以使用 typeof 简单判断下数据类型

  • 使用 Map
function unique(arr) {
let map = new Map()
return arr.filter((item) => {
return map.has(item) ? false : map.set(item, true)
})
}
  • indexOf 或 includes

不能过滤对象、NaN

function unique(arr) {
let list = []
if (!Array.isArray(arr)) {
throw new Error('type error')
}
for (let i = 0, l = arr.length; i < l; i++) {
let item = arr[i]
if (list.indexOf(item) === -1) {
list.push(item)
}
}
return list
}
  • 双层 for 循环

不能过滤对象、NaN

function unique(arr) {
// let l = arr.length
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
j--
}
}
}
return arr
}

实现扁平数组(降维数组)

  • 重写 concat 方法

只能处理二维数组

let arr = [[1, 2], [3, 4]]

Array.prototype.concat.apply([], arr) // [1, 2, 3, 4]
  • 使用 flat 方法

可以处理多维数组

let arr = [[1, 2], [3, 4]]

arr.flat(Infinity) // [1, 2, 3, 4]
  • 使用 toString + split

这种方法有些局限性,扁平化后的数组的每一项会变成字符串

let arr = [[1, 2], [3, 4]]

arr.toString().split(',') // [1, 2, 3, 4]
  • 递归
let source = [[1, 2], [3, 4]]
let arr = [] function flatFn(source) {
source.forEach(v => {
if(Array.isArray(v)){
flatFn(v)
} else {
arr.push(v)
}
})
}
flatFn(source)
console.log(arr) // [1,2,3,4]

实现取数组的最大值?

  • Math.max.apply(null, [4, 1, 2, 3])
  • Math.max(...[4, 1, 2, 3])

实现一个Flat?

let source = [[1, 2], [3, 4, [5, 6]]]

function flatFn(source, depth=1){
return source.reduce((pre,cur) => {
return Array.isArray(cur) && depth > 0 ? [...pre, ...flatFn(cur, depth-1)] : [...pre, cur]
}, [])
} console.log(flatFn(source, 1)) // [1, 2, 3, 4, Array(2)]
console.log(flatFn(source, 2)) // [1, 2, 3, 4, 5, 6]

工具类

实现深拷贝?

有如下的一个数据:

let obj = {
a: undefined,
b: 1.7976931348623157e10308,
c: -1.7976931348623157e10308,
d: new Date(),
e: new RegExp('\\w+'),
f: function () {
console.log(1)
}
}
  • 使用 JSON.parse(JSON.stringify(obj))

    弊端如下:

    • 如果 obj 里面有时间对象,时间将只是字符串的形式。而不是时间对象
    • 如果 obj 里有 RegExp、Error 对象,则序列化的结果将只得到空对象
    • 如果 obj 里有函数,undefined,则序列化的结果会把函数或 undefined 丢失
    • 如果 obj 里有 NaN、Infinity(正无穷大)和-Infinity(负无穷大),则序列化的结果会变成 null
    • 如果 obj 中的对象是有构造函数生成的,会丢弃对象的 constructor
  • 手写迭代拷贝

function deepClone(source) {
if (!source || typeof source !== 'object') {
return source
}
if (source instanceof Date) {
return new Date().setTime(source.getTime())
}
let newObj = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source[key] && typeof source[key] === 'object') {
newObj[key] = deepClone(source)
} else {
newObj[key] = source[key]
}
}
return newObj
}

排序算法

手写冒泡

名字的由来: 越大(或越小)的元素经过交换慢慢浮到数列的顶端。就如同饮料中的气泡最终会上浮到顶端一样,故名叫“冒泡排序”

规则如下:

  1. 外层循环和内层循环只需要循环 length - 1

两两比较,最后的两个数只需要比较一次就能确定两者的位置 比如 [2, 1, 3, 4, 5],2 和 1 只需要比较一次就能确定位置了[1, 2, 3, 4, 5]

  1. 内层循环在 length - 1 的基础上减去 i,也就是 length - 1 - i

每当外层 for 成功循环一次之后,内层 for 就可以少循环一次,这里注意是当外层 for 循环完毕之后

  1. 内层循环:用当前的值 a(arr[j])和下一个值 b(arr[j + 1])比较大小,如果 a 大于 b,则交换两数的位置,最终的目的是将最大的数移到数组最后面
let arr = [5, 4, 3, 2, 1]

function bubbleSort(arr) {
let len = arr.length
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
} bubbleSort(arr)

快排

规则如下:

  1. 在数组中,找到一个元素作为“基准”(pivot)
  2. 小于基准的元素,就移到“基准”的左边;大于“基准”的元素,就移到“基准”的右边
  3. 对“基准”左右两边的集合,进行递归,不断重复第一步和第二步,直到所有子元素只剩一个元素为止
function quickSort(arr) {
if (arr.length === 0) return arr
const pivotInx = Math.floor(arr.length / 2)
const pivot = arr.splice(pivotInx, 1)[0]
const left = []
const right = []
for (let i = 0; i < arr.length; i++) {
const item = arr[i]
if (item < pivot) {
left.push(item)
} else {
right.push(item)
}
}
return quickSort(left).concat([pivot]).concat(quickSort(right))
}

看代码

看以下代码会输出什么?

let a = { name: 'Jone' }
let b = a
a = { name: 'Sasa' }
console.log(b)

解答:

输出:{ name: 'Jone' }

这道题主要是考引用数据类型的特性 当 b = a 时,ab 指向同一个堆地址。 当 a = {name: 'Sasa'} a 被重新赋值,所以 a 指向新的堆地址,b 仍然是原来的堆地址

看以下代码会输出什么?

let a = 1
b = a
b = 2
console.log(a)

解答:

这道题主要是考基本数据类型的特性

其他

let a = null 有什么作用?

let a = null 一般用作手动释放该变量的内存,而不是等到离开作用域后被自动回收

如何阻止冒泡事件

function stopBubble(e) {
if (e && e.stopPropagation) {
// 非IE浏览器
e.stopPropagation()
} else {
//IE浏览器
window.event.cancelBubble = true
}
}

如何阻止浏览器默认事件

function stopDefault(e) {
//标准浏览器
if (e && e.preventDefault) {
e.preventDefault()
}
//个别IE
else {
window.event.returnValue = fale
return false
}
}

获取非行间样式

function getCss(curEle, attr) {
var val = null
try {
val = window.getComputedStyle(curEle, null)[attr]
} catch (e) {
val = curEle.currentStyle[attr]
}
return val
} getCss(div, 'width')

js面试题-代码实现的更多相关文章

  1. 10个常见的Node.js面试题

    如果你希望找一份有关Node.js的工作,但又不知道从哪里入手评测自己对Node.js的掌握程度. 本文就为你罗列了10个常见的Node.js面试题,分别考察了Node.js编程相关的几个主要方面. ...

  2. 所在实习公司的JS笔试题

    在班上无聊的时候看到了一份JS笔试题(我是电面进去的,没做过这份题~~),开始还觉得蛮简单......后来觉得还是很有意思的,贴出来一起看看. 题目一: if(!("a" in w ...

  3. Node.js面试题之2017

    译者按: 从ECMAScript标准,Node.js语法以及NPM模块角度来看,Node.js的发展让人目不暇接,那么面试题也得与时俱进. 原文: Node.js Interview Question ...

  4. vue.js面试题整理

    Vue.js面试题整理 一.什么是MVVM? MVVM是Model-View-ViewModel的缩写.MVVM是一种设计思想.Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务 ...

  5. 一道JS面试题引发的血案

    刚入职新公司,属于公司萌新一枚,一天下午对着屏幕看代码架构时. BI项目组长给我看了一道面试别人的JS面试题. 虽然答对了,但把理由说错了,照样不及格. 话不多说,直接上题: var a = 1; s ...

  6. js经典试题之常用的方法

    js经典试题之常用的方法 1.下面代码输出的值 let s = "bob" const replaced = s.replace('b', 'l') replaced === &q ...

  7. js经典试题之运算符的优先级

    js经典试题之运算符 1.假设val已经声明,可定义为任何值.则下面js代码有可能输出的结果为: console.log('Value is ' + (val != '0') ? 'define' : ...

  8. js经典试题之ES6

    js经典试题之ES6 1:在ECMAScript6 中,Promise的状态 答案:pending  resolved(fulfilled) rejected 解析: Promise对象只有三种状态: ...

  9. js经典试题之w3规范系列

    js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...

  10. js经典试题之原型与继承

    js经典试题之原型与继承 1:以下代码中hasOwnProperty的作用是? var obj={} …….. obj.hasOwnProperty("val") 答案:判断obj ...

随机推荐

  1. i mean

    马上教师节了,咱们不给教练整坨大的吗

  2. 谷歌浏览器页面乱码问题在浏览器端解决,charset下载安装;

    一   下载插件(百度网盘) 链接:https://pan.baidu.com/s/1o9Zuo2m 密码:rrcz 二    将下载好的插件拖到谷歌浏览器中 三    如果谷歌浏览器右下角出现如下图 ...

  3. Android平台下的cpu利用率优化实现

    目录 背景 CPU调频 概念 实现 验证 线程CPU亲和性 概念 亲和性控制 API 应用层控制实现 验证 线程优先级 概念 实现 验证 背景 为了进一步优化APP性能,最近针对如何提高应用对CPU的 ...

  4. pip下载太慢,换源

    1.安装pqi pip install pqi 2.改变pip源 比如换成清华源: pqi use tuna 3.显示当前源

  5. 70.http拦截能做些什么(问的是axios的封装)

    请求拦截器统一添加 token ,也可以手动的判断token是否过期  : 响应拦截器判断返回数据的逻辑处理,被动的判断token过期并处理 :

  6. 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-2-环境准备与搭建-基于Maven(详细教程)

    1.简介 上一篇宏哥已经讲解和分享了如何通过引入jar包来搭建Java+Playwright自动化测试环境,这一种是比较老的方法,说白了就是过时的老古董,但是我们必须了解和知道,其实maven搭建无非 ...

  7. 超越预期:Containerd 如何成为 Kubernetes 的首选容器运行时

    > 作者:尹珉,KubeSphere Ambassado,rKubeSphere Contributor,KubeSphere 社区用户委员会杭州站站长. 踏上 Containerd 技术之旅 ...

  8. KubeSphere 3.3.0 发布:全面拥抱 GitOps

    2022 年 6 月 27 日,KubeSphere 开源社区激动地向大家宣布,KubeSphere 3.3.0 正式发布! CNCF 发布的 2021 年度调查报告指出,容器和 K8s 的事实地位已 ...

  9. 在 KubeSphere 上部署 Apache Pulsar

    作者介绍:徐文涛,StreamNative Content Strategist,热爱云原生与开源技术,活跃于本地化/文档/技术博客贡献,持有 K8s CKA/CKAD/CKS 认证. Apache ...

  10. Ubuntu自动连接到虚拟专用网络

    在我们继续之前,我们所做的一个重要假设是,您已经拥有了虚拟专用网络客户端配置文件. 您可以通过以下链接在我们的上一指南中看到一个示例 Open虚拟专用网络 客户端配置文件: 在 CentOS 8/乌本 ...