js面试题-代码实现
新 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
}
排序算法
手写冒泡
名字的由来: 越大(或越小)的元素经过交换慢慢浮到数列的顶端。就如同饮料中的气泡最终会上浮到顶端一样,故名叫“冒泡排序”
规则如下:
- 外层循环和内层循环只需要循环
length - 1
两两比较,最后的两个数只需要比较一次就能确定两者的位置 比如 [2, 1, 3, 4, 5],2 和 1 只需要比较一次就能确定位置了[1, 2, 3, 4, 5]
- 内层循环在
length - 1的基础上减去i,也就是length - 1 - i
每当外层 for 成功循环一次之后,内层 for 就可以少循环一次,这里注意是当外层 for 循环完毕之后
- 内层循环:用当前的值 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)
快排
规则如下:
- 在数组中,找到一个元素作为“基准”(pivot)
- 小于基准的元素,就移到“基准”的左边;大于“基准”的元素,就移到“基准”的右边
- 对“基准”左右两边的集合,进行递归,不断重复第一步和第二步,直到所有子元素只剩一个元素为止
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 时,a 和 b 指向同一个堆地址。 当 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面试题-代码实现的更多相关文章
- 10个常见的Node.js面试题
如果你希望找一份有关Node.js的工作,但又不知道从哪里入手评测自己对Node.js的掌握程度. 本文就为你罗列了10个常见的Node.js面试题,分别考察了Node.js编程相关的几个主要方面. ...
- 所在实习公司的JS笔试题
在班上无聊的时候看到了一份JS笔试题(我是电面进去的,没做过这份题~~),开始还觉得蛮简单......后来觉得还是很有意思的,贴出来一起看看. 题目一: if(!("a" in w ...
- Node.js面试题之2017
译者按: 从ECMAScript标准,Node.js语法以及NPM模块角度来看,Node.js的发展让人目不暇接,那么面试题也得与时俱进. 原文: Node.js Interview Question ...
- vue.js面试题整理
Vue.js面试题整理 一.什么是MVVM? MVVM是Model-View-ViewModel的缩写.MVVM是一种设计思想.Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务 ...
- 一道JS面试题引发的血案
刚入职新公司,属于公司萌新一枚,一天下午对着屏幕看代码架构时. BI项目组长给我看了一道面试别人的JS面试题. 虽然答对了,但把理由说错了,照样不及格. 话不多说,直接上题: var a = 1; s ...
- js经典试题之常用的方法
js经典试题之常用的方法 1.下面代码输出的值 let s = "bob" const replaced = s.replace('b', 'l') replaced === &q ...
- js经典试题之运算符的优先级
js经典试题之运算符 1.假设val已经声明,可定义为任何值.则下面js代码有可能输出的结果为: console.log('Value is ' + (val != '0') ? 'define' : ...
- js经典试题之ES6
js经典试题之ES6 1:在ECMAScript6 中,Promise的状态 答案:pending resolved(fulfilled) rejected 解析: Promise对象只有三种状态: ...
- js经典试题之w3规范系列
js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...
- js经典试题之原型与继承
js经典试题之原型与继承 1:以下代码中hasOwnProperty的作用是? var obj={} …….. obj.hasOwnProperty("val") 答案:判断obj ...
随机推荐
- LeetCode 407. 接雨水 II (优先队列)
参考 优先队列的思路解决接雨水II,逐行解释 从最外圈开始不断向内遍历,如果内部的高度小于外部的高度,则证明该位置可以蓄水,否则不能,水会顺着该外圈流出去. 每次都处理外圈高度最小的那个位置 a,遍历 ...
- 调查报告解读之国外数据库篇:MySQL国内使用率第一,多少企业有意替换国外产品?
为了解数据库行业以及从业人员的现状.数据库选型.中国数据库的发展趋势等,墨天轮于2022年开始进行问卷收集,历时24天,共征集到有效问卷3476份,并于2月10日整理发布了<2022年墨天轮数据 ...
- 墨天轮沙龙 | SphereEx代野:Apache ShardingSphere-从中间件到分布式生态演进之路
在9月22日举办的[墨天轮数据库沙龙第十期-国产中间件专场]中,SphereEx 解决方案专家 代野分享了Apache ShardingSphere:从中间件到分布式生态演进之路>主题演讲,本文 ...
- 08-react修改state数据驱动视图UI的更新【注意和vue的区别】
// setState 修改状态 如果是直接修改页面不会改变 使用 setState 修改数据 才会驱动视图的改变 // setState 的原理:修改玩状态之后会调用 render 函数 impor ...
- MSF 入侵安卓手机
生成木马文件 msfvenom -p android/meterpreter/reverse_tcp LHOST=192.168.135.247 LPPRT=5555 进行文件传输: python3 ...
- 妙用编辑器:把EverEdit变成计算器
妙用编辑器:把EverEdit变成计算器 应用场景 日常工作过程中,会存在需要计算一些数据的场景,调用系统的计算器当然可以完成这项工作,但是需要来回切换,且系统自带的计算器没有表达式计算功能,真是不方 ...
- R语言经典统计分析
经典统计分析包括了许多常用的统计方法和技术,用于数据的描述.推断和建模.本节将介绍经典统计分析方法(包括t检验.方差分析.卡方检验.线性回归)在R语言中的实现. 5.1.1 t检验 样本均值(sam ...
- 基于 WeDataSphere Prophecis 与 KubeSphere 构建云原生机器学习平台
KubeSphere 开源社区的小伙伴们,大家好.我是微众银行大数据平台的工程师周可,接下来给大家分享的是基于 WeDataSphere 和 KubeSphere 这两个开源社区的产品去构建一个云原生 ...
- 在 KubeSphere 中使用 DevOps 部署 Java 微服务配置监控预警
作者:酱油瓶,携程后端技术专家, KubeSphere 社区用户 开发 Java 微服务并引入监控组件 我们基于 Spring Cloud +Nacos 开发 Java 微服务,Java 服务开发不做 ...
- 一些新奇的玩意【php篇--持续更新】
人不进步就等于退步! 接触越多的人以及事就能学到更多的东西. 以下仅为本人记录的一些新奇的东西,不喜勿喷! 1.??运算符号,在新的项目中突然发现很多红线报错,还以为是错误!看了下,是??运算的问题, ...