更新中
arguments转数组
-
arguments
是一个对象,只是属性从0开始排列
1. Array.prototype.slice()
const arr = Array.prototype.slice.call(arguments)
2. Array.from()
const arr = Array.from(arguments)
3. Array.prototype.concat()
const arr = Array.prototype.concat.apply([], arguments)
4. 展开运算符
const arr = [...arguments]
中断forEach返回值
在forEach中使用return
不会返回,需要在try-catch中抛出错误
try {
[1, 2, 3].forEach(item => {
throw new Error('return')
})
} catch (e) {
console.log(e)
}
判断数组包含某个值
1. Array.prototype.indexOf()
[1, 2, 3].indexOf(1) > -1
2. Array.prototype.includes()
[1, 2, 3].includes(1)
3. Array.prototype.find()
[1, 2, 3].find(item => item === 1)
4. Array.prototype.findIndex()
返回的是下标
[1, 2, 3].findIndex(item => item > 1)
数组扁平化
const target = [1, [2, 3], [4, [5, 6, 7, [8]]
1. flat(ES6)
const arr = target.flat(Infinity)
2. replace + split
const arr = JSON.stringify(target).replace(/(\[|\]/g, '').split(',')
3. 递归
let res = []
const fn = function(arr) {
arr.forEach(item => {
Array.isArray(item) ? arguments.callee(item) : (res.push(item))
})
}
4. reduce
const fn = function(arr) {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? arguments.callee(cur) : cur)
}, [])
}
5. 展开运算符
while(target.some(Array.isArray) {
target = [].concat(...target)
}
this指向
总的来说个人觉得是谁调用就指向谁,并不是定义的时候决定的
1. 全局上下文
全局默认指向window,严格模式下默认指向undefined
fn() // 相当于 window.fn()
2. 直接调用
const obj = {
fn: function () {}
}
const a = obj.fn
a() // 相当于全局上下文,this指向window
3. 对象.方法调用
const obj = {
fn: function () {}
}
obj.fn() // 满足谁调用就指向谁,this是指向obj的
4. DOM事件绑定
onxxx 和 addEventListener中,this指向的是被绑定的元素
5. new XXX()
new 中,this永远指向实例,不可更改
6. 箭头函数
箭头函数没有this,指向最近的非箭头函数的this
浅拷贝
我们都知道对象其实也叫做引用类型,保存的是引用地址,两个相同引用地址对象,修改任意一个会造成相互影响;浅拷贝能对每一个值都是基本类型的数组/对象进行拷贝,但是如果某一个值的类型是对象就不能达到拷贝的效果
const arr = [1, 2, 3]
1. slice()
arr.slice()
2. concat()
[].concat(arr)
3. 展开运算符
const newArr = [...arr]
const obj = { a: 1 }
const newObj = { ...obj }
4. 手动实现
function shallowClone(target) {
if (typeof target === 'object' && target !== null) {
const cloneTarget = Array.isArray(target) ? [] : {}
Object.entries(target).forEach([key, value] => {
cloneTarget[key] = value
})
return cloneTarget
} else {
return target
}
}
深拷贝
深拷贝能实现对对象嵌套的拷贝
1. JSON.parse(JSON.stringify(obj))
const obj = { a: 1 }
const deepClone = JSON.parse(JSON.stringify(obj))
缺点: JSON对象是为了json数据格式序列化用的,json作为js数据格式的一种简单版本,是不支持复杂的类型比如Set,Map,RegExp,Function等,并且对于循环嵌套也不能解决,毕竟是有一个转换为字符串的过程
2. 手动
const isObject = (target) => (typeof target === 'object' || typeof target === 'function') && target !== null
const deepClone = function (target, map = new WeakMap()) {
if (map.get(target)) {
return target
}
else if (isObject(target)) {
map.put(target, true)
const deepTarget = Array.isArray(target) ? [] : {}
Object.entries(target).forEach([key, value] => {
deepTarget[key] = deepClone(value, map)
})
return
} else {
return target
}
}