数组去重
Set + Array
function uniqueArray(arr) {
return Array.from(new Set(arr));
};
splice
function uniqueArray(arr) {
for(let i = 0; i < arr.length - 1; i++) {
for(let j = i + 1; j < arr.length; j++) {
if(arr[j] === arr[i]) {
arr.splice(j--,1);
}
}
}
return arr
};
扁平化数组
es6 中 flat
[1,2,[3,3]].flat() // [1,2,3,3]
reduce
function flat(arr) {
return arr.reduce((prev, next) => {
return prev.concat(Array.isArray(next) ? flat(next) : next);
}, [])
}
自定义 instanceof
function customInstanceof(left, right) {
let proto = Object.getPrototypeOf(left);
while(proto) {
if (proto === right.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
实现 getElementById
递归
const getElementById = (node, id) => {
if (node == null) {
return null;
}
if (node.id === id) {
return node;
}
for (let i = 0; i < node.children.length; i++) {
const result = getElementById(node.children[i], id);
if (result != null) {
return result;
}
}
return null;
}
非递归
const nextElement = (node) => {
if (node.children.length) {
return node.children[0]
}
if (node.nextElementSibling) {
return node.nextElementSibling;
}
while(node.parentNode) {
if (node.parentNode.nextElementSibling) {
return node.parentNode.nextElementSibling;
}
node = node.parentNode;
}
return null
}
const getElementById = (node, id) => {
while(node) {
if (node.id === id) {
return node;
}
node = nextElement(node);
}
return node;
}
实际上浏览器是使用的一个映射,直接将id映射到dom上
call、apply、bind
call
Function.prototype.customCall = function(obj, ...args) {
const call = Symbol('call');
const thisObject = obj || window;
thisObject[call] = this;
const result = obj[call](...args);
delete thisObject[call];
return result;
}
apply
Function.prototype.customApply = function(obj, ...args) {
const call = Symbol('call');
const thisObject = obj || window;
thisObject[call] = this;
const result = obj[call](...args);
delete thisObject[call];
return result;
}
bind
Function.prototype.myBind = function(obj, ...args) {
const self = this;
function result (otherArgs) {
const allArgs = args.concat(otherArgs);
return self.apply(this instanceof self ? this : obj, allArgs);
}
result.prototype = Object.create(self.prototype);
return result;
}
bind
利用了 apply
,处理了通过 new
调用的情况
new
function customNew(constructorFunc, ...args) {
const obj = {};
Object.setPrototypeOf(obj, constructorFunc.prototype);
// const obj = Object.create(constructorFunc.prototype);
const result = constructorFunc.apply(obj, args);
return result instanceof Object ? result : obj;
}
函数式
curry
function curry(func) {
const argLength = func.length;
return function deepCurry(...args) {
if (args.length >= argLength) {
return func.apply(null, args);
} else {
return function(...args2) {
return deepCurry.apply(null, args.concat(args2));
}
}
}
}
compose
function compose(...args) {
return args.reduce((final, next) => {
return (...args) => {
return final(next(...args));
}
}, result => result);
}
浅拷贝
数组
API解决
Array.from()
[].concat()
Array.propertype.slice.call()
[...arr]
对象
API解决
Object.assign
{...otherObj}
自定义
function shallowClone(source) {
const result = Object.create(null);
for(let i in source) {
if(source.hasOwnProperty(i)) {
result[i] = source[i]
}
}
return result
}
深拷贝
自定义
function cloneDeep(source) {
if(source == null) {
return source;
}
if (Array.isArray(source)) {
return source.map(cloneDeep);
};
if (typeof source === 'object') {
const result = Object.create(null);
for (const key in source) {
if (source.hasOwnProperty(key)) {
result[key] = cloneDeep(source[key]);
}
}
return result
}
return source;
}
JSON.parse(JSON.stringify())
缺陷:函数会在转换中丢失
Base64转File
function dataURLtoFile(str, filename) {
const [type, content] = str.split(',')
const bstr = window.atob(content)
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, {
type: type.replace(/(data:)|(;base64)/g, ''),
})
}
File 转 Base64
这里得通过 FileReader
,而且是异步操作
function fileToBase64(file) {
return new Promise(function(resolve, reject) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = (event) => {
resolve(event.target.result)
}
})
}
ArrayToTree
const toTree = (parentId, array) => {
let children = [];
let len = array.length;
for (let i = 0; i < len; i++) {
let node = array[i];
if (node.parentId === parentId) {
children.push({
id: node.id,
val: node.val,
children: toTree(node.id, array)
})
}
}
return children;
}
const arrayToTree = (array) => {
let root = array[0];
array.shift();
let tree = {
id: root.id,
val: root.val,
children: array.length ? toTree(root.id, array) : []
}
return tree;
}