实现一个简单的闭包
// 实现隔一秒输出一个数字,数字递增
// 1.利用匿名自执行函数创建闭包实现
for(var i = 0; i < 5; i++){
(function(arg){
setTimeout(function run(){
console.log(arg)
}, arg*1000)
})(i)
}
// 2.使用 let 实现
for(let i = 0; i < 5; i++){
setTimeout(()=>{
console.log(i)
},i*1000)
}
节流和防抖
// 节流函数(在规定的时间间隔内只触发一次事件处理函数,如果多次触发,则什么也不做)
function throttle(func, wait){
let start = Date.now()
return function(){
let end = Date.now()
if(end - start > wait){
return func.apply(this, arguments)
start = end
}
}
}
// 防抖函数(在规定的时间间隔内只触发一次事件处理函数,如果多次触发则重新设置计时器,即把在规定时间内多次触发的事件合并为一次)
function debounce(func, wait){
let timer = null
return function() {
if(timer !== null){
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
func.apply(this, arguments)
}, wait)
}
}
实现 sleep 函数
// 1.使用 for 循环实现
function sleep(func, wait) {
let start = Date.now()
while(Date.now() - start < wait){}
func()
}
// 2.setTimeout
function sleep(func, wait) {
setTimeout(func, wait)
}
// 3.promise
function sleep(func, wait) {
new Promise((resolve) => {
setTimeout(resolve, wait)
}).then(value => {
func()
})
}
// 4.async
async function sleep(func, wait) {
await new Promise((resolve) => {
setTimeout(resolve, wait)
})
func()
}
实现 bind、apply、call
// bind
Function.prototype.bind = function(context){
let args = [].slice.call(arguments, 1)
let that = this
function f(){
return that.apply(this instanceof f ? this : context, args.concat([].slice.call()))
}
f.prototype = Object.create(this.prototype)
return f;
}
// apply
Function.prototype.apply(context, arg) {
if(typeof this !== 'function') {
throw new Error('类型错误')
}
context = context || window
context.func = this
let result = context.func(...arg)
delete context.func
return result
}
// call
Function.prototype.call(context, ...arg) {
if(typeof this !== 'function') {
throw new Error('类型错误')
}
context = context || window
context.func = this
let result = context.func(...arg)
delete context.func
return result
}
手写 new
function new (Func, ...arg){
let obj = {}
obj.__proto__ = Func.prototype
let res = Func.call(obj, ...arg)
return res instanceof Object ? res : obj
}
实现 instanceof
// instanceof 是通过原型链判断的,即判断构造函数的原型对象是否在 obj 的原型链上
function InstanceOf(obj, Fun){
let left = onj.__proto__
let right = Fun.prototype
while(1){
if(left === null) {
return false
}
if(left === right){
return true
}
left = left.__proto__
}
}
使用 Promise 封装 ajax
function ajax(method, url){
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open(method, url, true)
xhr.onreadystatechange = function(){
if(this.readyState === 4 && this.status === 200){
resolve(this.responseText)
}
}
xhr.send(null)
})
}
数组去重
// indexOf 去重
function qu(arr){
let res = []
arr.forEach((item) => {
if(res.indexOf(item) === -1){
res.push(item)
}
})
return res
}
// ES6 去重
[...new Set(arr)]
深拷贝和浅拷贝
// 1.深拷贝
// 方法1
let newObj = JSON.parse(JSON.stringify(obj))
// 方法2
function deepClone(obj){
let newObj = Array.isArray(obj) ? [] : {}
for(let i in obj){
newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
}
return newObj
}
// 2.浅拷贝
// 方法1
let newObj = {...obj}
// 方法2
let newObj = Object.assign({}, obj)
函数柯里化
// 将接受多个参数的函数转换成接受一个或多个参数的函数,并返回新的函数,等获得足够的参数后执行该函数
function curry(func, ...arg){
return function(){
let args = arg.concat([].slice.call(arguments))
if(args.length >= func.length){
func.apply(this, args)
} else {
return curry(func, ...args)
}
}
}
数组扁平化
function flatten(arr){
let res = []
while(arr.length > 0){
let tmp = arr.pop()
if(Array.isArray(tmp)){
arr.push(...tmp)
}else{
res.unshift(tmp)
}
}
return res
}
未完,待续…
如有错误,希望指正,不胜感激!