-
深拷贝
- 注意判断值类型和引用类型
- 注意判断是数组还是对象
- 递归
function deepClone(obj = {}) { if (typeof obj !== 'object' || !obj) { // obj 是 null, 或者不是对象和数组,直接返回 return obj; } // 初始化返回结果 let result; if (obj instanceof Array) { result = []; } else { result = {}; } for (let key in obj) { // 保证key不是原型的属性 if (obj.hasOwnProperty(key)) { // 递归调用 result[key] = deepClone(obj[key]); } } return result; }
-
字符串拼接
const a = 100 + 10 // 110 const b = 100 + '10' // '10010' const c = true + '10' // 'true10'
-
== 运算符
100 == '100' // true 0 == '' // true 0 == false // true false == '' // true null == undefinde
-
逻辑运算
// 以下是 falsely 变量。除此之外都是 truly 变量 !!0 === false !!NaN === false !!null === false !!undefined === false !!false === false
-
typeof 能判断哪些类型
- undefined string number boolean symbol
- function
- object(注意,typeof null === ‘object’)
-
如何准确判断一个变量是数组
a instanceof Array
-
var 和 let const 的区别
- var 是 ES5 语法,let const 是 ES6 语法;var 有变量提升。
- var 和 let 是变量,可修改;const 是常量,不可修改。
- let const 有块级作用域,var 没有。
-
列举强制类型转换和隐式类型转换
- 强制:parseInt parseFloat toString 等。
- 隐式:if、逻辑运算、==、+ 拼接字符串。
-
手写深度比较,模拟 lodash isEqual
function isObject(obj) { return typeof obj === 'object' && obj !== null; } function isEqual(obj1, obj2) { if (!isObject(obj1) || !isObject(obj2)) { return obj1 === obj2; } if (obj1 === obj2) { return true; } // 两个都是对象或数组,而且不相等 // 1.先取出 obj1 和 obj2 的 keys ,比较个数 const obj1Keys = Object.keys(obj1); const obj2Keys = Object.keys(obj2); if (obj1Keys.length !== obj2Keys.length) { return false; } // 2.以 obj1 为基准,和 obj2 一次递归比较 for (let key in obj1) { const res = isEqual(obj1[key], obj2[key]); if (!res) return false; } return true; }
-
split() 和 join() 的区别
'1-2-3'.split('-') // [1, 2, 3] [1, 2, 3].join('-') // '1-2-3'
-
数组的pop push unshift shift分别是做什么的
- pop 从数组中删除最后一个元素,并返回该值,此方法更改数组长度
- 將一个或多个元素添加到数组末尾,并返回数组的长度,此方法更改数组长度
- 将一个或多个元素添加到数组的首部,并返回数组的长度,此方法修改原数组
- 从数组中删除第一个元素,并返回删除的值,该方法修改原数组
-
get 和 post 的区别
- get 一般用于查询操作,post 一般用户提交操作。
- get 参数拼接在 url 上,post 放在请求体内。
- 安全性:post易于防止CSRF。
-
函数 call 和 apply 的区别
fn.call(this, p1, p2, p3)
fn.apply(this, arguments)
-
函数声明和函数表达式的区别
- 函数声明 function fn() {};
- 函数表达式 const fn = function() {};
- 函数声明会在代码执行前预加载,而函数达式不会
-
new Object() 和 Object.create() 区别
- {} 等于 new Object(),原型 Object.prototype
- Object.create(null) 没有原型
- Object.create({…}) 可指定原型
-
手写字符串 trim 保证浏览器兼容性
String.prototype.trim = function () { return this.replace(/^\s+/, '').replace(/\s+$/, ''); }
-
手写数组 flatern,考虑多层级
function flat(arr) { // 验证 arr 中,还有没有深层数组 const isDeep = arr.some(item => item instanceof Array) if (!isDeep) { return arr } const res = [].concat.apply([], arr) return flat(res) }
-
数组去重
// 传统方式 function unique(arr) { const arr = []; arr.forEach(item => { if (res.indexOf(item) < 0) { res.push(item) } }) return res } // 使用 Set function unique(arr) { const set = new Set(arr) return [...set] }
-
介绍 RAF requetAnimateionFrame
- 要想动画流畅,更新频率要 60帧/s,即 16.67ms 更新一次视图。
- setTimeout 要手动控制频率,而 RAF 浏览器会自动控制。
- 后台标签或隐藏 iframe 中,RAF 会暂停,而 setTimeout 依然执行。
-
Map 和 Object 区别
- API 不同,Map 可以以任意类型为 key
- Map 是有序结构
- Map 操作同样很快
-
Set 和数组的区别
- API 不同
- Set 元素不能重复
- Set 是无序结构,操作很快
-
WeakMap 和 WeakSet
- 弱引用,防止内存泄漏
- WeakMap 只能用对象作为 key,WeakSet 只能用对象做 value
- 没有 forEach 和 size,只能用 add delete has
JS 面试题常见知识点(一)
最新推荐文章于 2024-07-22 15:13:59 发布