/******************* 继承 *************************/
// 寄生继承
function Animal(name, age) {
this.name = name
this.age = age
}
Animal.prototype.eat = () => {
console.log('eat')
}
function Dog(name, age, hoppy) {
Animal.call(this, name, age)
this.hoppy = hoppy
}
const inhertParent = (child, Parent) => {
const prototype = Object.create(Parent.prototype)
child.prototype = prototype
child.prototype.constructor = Parent
}
inhertParent(Dog, Animal)
/******************* 防抖与节流 *************************/
// 防抖
let debounce = (fn, delay) => {
let timer = null
return function(...args) {
const context = this;
if(timer) {
clearTimeout(timer)
timer = null
}
setTimeout(()=> {
fn.apply(context, args)
}, delay)
}
}
// 节流
let throttle = (fn, delay) => {
let currentTime = Date.now()
return function(...args) {
const context = this
const nowTime = Date.now()
if(currentTime - nowTime >= delay) {
return fn.apply(context, args)
currentTime = Date.now()
}
}
}
/******************* 函数借用三剑客 *************************/
// call
// fn.call(this, arg1, arg2)
function myCall(context=window, ...args) {
if(!this) {
throw new Error('error')
}
let result = null
context.fn = this
result = context.fn(...args)
delete context.fn
return result
}
// apply
// fn.apply(this, ...args)
function myCall(context=window, ...args) {
if(!this) {
throw new Error('error')
}
let result = null
context.fn = this
if(args && args.length > 0) {
result = context.fn(...args)
} else {
result = context.fn()
}
delete context.fn
return result
}
// bind
// fn.bind(this, arg1, arg2...)
function myCall(context=window, ...args) {
if(!this) {
throw new Error('error')
}
const self = this
return function() {
return self.apply(context, args)
}
}
/******************* 去重三版 *************************/
// map版本
function removeDuplicate(arr) {
let map = new Map()
let result = []
for(let i=0; i<arr.length; i++) {
if(!map.has(arr[i])) {
map.set(arr[i], arr[i])
result.push(arr[i])
}
}
return result
}
// indexof版本
function removeDuplicateIndexOf(arr) {
let result = []
for(let i=0; i<arr.length; i++) {
if(result.indexOf(arr[i]) === -1) {
result.push(arr[i])
}
}
return result
}
// includes版本
function removeDuplicateIncludes(arr) {
let result = []
for(let i=0; i<arr.length; i++) {
if(!result.includes(arr[i])) {
result.push(arr[i])
}
}
return result
}
/******************* 扁平化数组 *************************/
// ES6
let arr = [1,2,3,[4,5,[6,[7,8,[9,10]]]]];
// console.log(arr.flat(Infinity))
// 递归
function flat(arr) {
let result = []
for(let i=0;i<arr.length;i++) {
const current = arr[i]
if(Array.isArray(current)) {
result = [...result, ...flat(current)]
} else {
result = [...result, current]
}
}
return result
}
// console.log(flat(arr))
/******************* 数组转换成树 *************************/
// 转换前:
let source = [{
id: 1,
pid: 0,
name: 'body'
}, {
id: 2,
pid: 1,
name: 'title'
}, {
id: 3,
pid: 2,
name: 'div'
}]
// 转换为:
let tree = [{
id: 1,
pid: 0,
name: 'body',
children: [{
id: 2,
pid: 1,
name: 'title',
children: [{
id: 3,
pid: 1,
name: 'div'
}]
}]
}]
[{
id: 1,
pid: 0,
name: 'body'
}, {
id: 2,
pid: 1,
name: 'title'
}, {
id: 3,
pid: 2,
name: 'div'
}]
function convertTree(arr) {
if(!Array.isArray(arr)) return arr
let map = {}
let result = []
arr.forEach(item => {
map[item.id] = item
})
arr.forEach(item => {
let parent = map[item.pid]
if(parent) {
((parent.children) || (parent.children = [])).push(item)
} else {
result.push(item)
}
})
return result
}
// console.log(convertTree(source))
/******************* Url对象解析 *************************/
let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
// console.log(parseParam(url))
/* 结果
{ user: 'anonymous',
id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
city: '北京', // 中文需解码
enabled: true, // 未指定值得 key 约定为 true
}
*/
function parseParam(url) {
let param = url.split('?')[1]
let paramArr = param.split('&')
let result = {}
paramArr.forEach(item => {
if(item.indexOf('=')!==-1) {
const [key, value] = item.split('=')
if(result[key]) {
const lastValue = result[key]
result[key] = Array.isArray(lastValue) ? [...lastValue, value] : [lastValue, value]
} else {
result[key] = decodeURIComponent(value)
}
} else {
result[item] = true
}
})
return result
}
/******************* 千分位分割 *************************/
const cash = 1234567
function getReverse(str) {
return str.split('').reverse().join('')
}
function formatCash(number) {
number = number + ''
let cash = number
let last = ''
if(cash.indexOf('.') > -1) {
cash = number.split('.')[0]
last = number.split('.')[1]
}
cash = getReverse(cash)
const count = Math.ceil(cash.length / 3)
let i = 0
let result = []
while(i !== count) {
let sliceStr = cash.slice(i*3 , ++i * 3)
sliceStr = getReverse(sliceStr)
result = [sliceStr, ...result]
}
return `${result.join(',')}.${last}`
}
// console.log(formatCash(cash))
// 根据string可以直接通过索引的方式取值
function format(number, thousandsSeperator) {
const s = String(number)
let r = ''
for (let i = s.length - 1; i >= 0; i--) {
const seperator = (s.length - i - 1) % 3 ? '' : thousandsSeperator
r = `${s[i]}${seperator}${r}`
}
return r.slice(0, -1)
}
format(cash, ',')
/******************* 洗牌算法(打乱数组) *************************/
// 思路就是每次从数组的第n个取值(n从数组尾部开始),
// 在随机生成0 ~ n-1的索引然后互相交换他们的值即可;
function shuffle(arr) {
let currentIndex = arr.length;
while(currentIndex) {
const randomIndex = Math.floor(Math.random() * currentIndex--)
const currentValue = arr[currentIndex]
arr[currentIndex] = arr[randomIndex]
arr[randomIndex] = currentValue
}
return arr
}
// console.log(shuffle([1,2,3]))
/*
请实现一个 sum 函数,接收一个数组 arr 进行累加,并且只能使用add异步方法
add 函数已实现,模拟异步请求后端返回一个相加后的值
*/
function add(a, b) {
return Promise.resolve(a + b);
}
// async
async function asyncSum(arr) {
let result = 0
for(let i = 0; i < arr.length ; i++) {
result = await add(result, arr[i])
}
console.log(result)
return result
}
promiseSum([1,2,3])
// 斐波那契数列
// 本质就是 0 1,从2开始等于前面两个数的和
function fn(n) {
let n1 = 1, n2 = 1
for(let i = 2;i<n;i++) {
[n1, n2] = [n2, n1 + n2]
}
return n2
}
function fn1(n) {
let n1 = 1, n2 = 1, sum;
for(let i=2; i<n;i++) {
sum = n1 + n2
n1 = n2
n2 = sum
}
return sum
}
// interval
function mySetInterval(fn, timeout) {
var timer = {
flag: true
};
function interval() {
if (timer.flag) {
fn();
setTimeout(interval, timeout);
}
}
setTimeout(interval, timeout);
return timer;
}
console