1.Object.create()
function create(obj) {
function F() {}
F.prototype = obj
return new F()
}
const person = { age: 18 }
const child1 = Object.create(person)
const child2 = create(person)
console.log(child1, child1.age)
console.log(child2, child2.age)
2.instanceof
function Person(age) {
this.age = age
}
const A = new Person(10)
console.log(A instanceof Person)
console.log(A instanceof Object)
function myInstanceof(left, right) {
let proto = Object.getPrototypeOf(left)
const prototype = right.prototype
while (true) {
if (!proto) return false
if (proto === prototype) return true
proto = Object.getPrototypeOf(proto)
}
}
console.log(myInstanceof(A, Person))
console.log(myInstanceof(A, Object))
3.new
function myNew(fn, ...args) {
const obj = {}
obj.__proto__ = fn.prototype
const value = fn.apply(obj, args)
return value instanceof Object ? value : obj
}
function myNew(fn, ...args) {
const obj = Object.create(fn.prototype)
const value = fn.apply(obj, args)
return value instanceof Object ? value : obj
}
4.promise
5-1.防抖
function _debounce(fn, time) {
let timer = null
return function (...arg) {
timer && clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arg)
}, time)
}
}
5-2.节流
function changeColor(params) {
let r = Math.floor(Math.random() * 255)
let g = Math.floor(Math.random() * 255)
let b = Math.floor(Math.random() * 255)
document.body.style.backgroundColor = `rgb(${r},${g},${b})`
}
window.addEventListener("resize", _throttle(changeColor, 1000))
function _throttle(fn, time) {
let timer = null
return function (...arg) {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, arg)
timer = null
}, time)
}
}
6.手写call
function person(a, b, c) {
console.log(this)
console.log(this.name)
console.log(a, b, c)
}
const a = { name: "a" }
Function.prototype.myCall = function (content) {
if (typeof this !== "Function") {
return
}
const myArguments = [...arguments].slice(1)
content = content || window
content.fn = this
const res = content.fn(...myArguments)
delete content.fn
return res
}
const res = person.myCall(a, "h", "e", "y")
7.手写apply
function person(a, b) {
console.log(this)
console.log(this.name)
console.log(a, b)
}
const a = { name: "a" }
Function.prototype.myApply = function (content) {
if (typeof this !== "function") {
return
}
content = content || window
content.fn = this
let res = null
if (arguments[1]) {
res = content.fn(...arguments[1])
} else {
res = content.fn()
}
delete content.fn
return res
}
person.myApply(a, ["x", "y"])
8.手写bind
function person(a, b) {
console.log(this)
console.log(a, b)
return 123
}
Function.prototype.myBind = function (ctx) {
const arg = Array.prototype.slice.call(arguments, 1)
const fn = this
return function F() {
const restArg = Array.prototype.slice.call(arguments, 0)
const myArg = [...arg, ...restArg]
if (Object.getPrototypeOf(this) === F.prototype) {
return new fn(...myArg)
} else {
return fn.apply(ctx, myArg)
}
}
}
const newPerson = person.myBind("ctx", 1)
const res = new newPerson(2)
console.log(res)
9.柯里化
function fn(x, y, z) {
console.log(x + y + z)
return x + y + z
}
fn(1, 2, 10)
fn(1, 3, 10)
fn(1, 4, 10)
fn(1, 4, 20)
g = curry(fn, 1)
g(2, 10)
g(3, 10)
g(4, 10)
g(4, 20)
function fn(x, y, z) {
console.log(x + y + z)
return x + y + z
}
function curry(fn) {
const arg1 = Array.prototype.slice.call(arguments, 1)
return function () {
const arg2 = [...arguments]
const args = [...arg1, ...arg2]
if (args.length >= fn.length) {
return fn(...args)
} else {
return curry.call(null, fn, ...args)
}
}
}
const g = curry(fn, 1)
const h = curry(g, 4)
function curry(fn, ...args) {
return args.length >= fn.length ? fn(...args) : curry.bind(null, fn, ...args)
}
10.AJAX
const server_url = "./herolist.json"
const xhr = new XMLHttpRequest()
xhr.open("GET", server_url)
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
if (xhr.status === 200) {
console.log("success,连接成功", this.response)
} else {
console.log("error,连接失败", this.statusText)
}
}
xhr.onerror = function () {
console.error("错误", this.statusText)
}
xhr.responseType = "json"
xhr.send(null)
11.promise封装ajax请求
function getJson(params) {
const myPromise = new Promise((resolve, reject) => {
const server_url = "./herolist.json"
const xhr = new XMLHttpRequest()
xhr.open("GET", server_url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
if (xhr.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.onerror = function () {
reject(new Error(this.statusText))
}
xhr.responseType = "json"
xhr.setRequestHeader("Accept", "application/json")
xhr.send(null)
})
return myPromise
}
12.深拷贝
const obj = {
arr: [1, 2],
a: 4,
}
obj.sub = obj
obj.arr.push(obj)
function deepClone(obj) {
const cache = new WeakMap()
function _deepClone(obj) {
if (obj === null || typeof obj !== "object") {
return obj
}
if (cache.has(obj)) {
return cache.get(obj)
}
const res = Array.isArray(obj) ? [] : {}
cache.set(obj, res)
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
res[key] = _deepClone(obj[key])
}
}
return res
}
return _deepClone(obj)
}
const newObj = deepClone(obj)
console.log(newObj.arr !== obj.arr)
console.log(newObj.sub !== obj.sub)
console.log(newObj.arr[2] !== obj)
console.log(newObj.arr[2] === newObj)
13.打乱数组
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const randomNum = Math.round(Math.random() * (arr.length - 1))
function shuffle(arr) {
let _arr = arr.slice()
for (let i = 0; i < _arr.length; i++) {
;[_arr[i], _arr[randomNum]] = [_arr[randomNum], _arr[i]]
}
return _arr
}
const newArr = shuffle(arr)
console.log(newArr)
14.数组扁平化
const arr = [1, 2, [3, 4], [5, [6, 7]]]
function myFlat(arr) {
let result = []
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = [...result, ...myFlat(arr[i])]
} else {
result.push(arr[i])
}
}
return result
}
console.log(myFlat(arr))
15.手写flat
const arr = [1, 2, [3, 4], [5, [6, 7]]]
Array.prototype.myFlat = function () {
let result = []
for (let i = 0; i < this.length; i++) {
if (Array.isArray(this[i])) {
result = [...result, ...this[i].myFlat()]
} else {
result.push(this[i])
}
}
return result
}
const newArr = arr.myFlat()
console.log(newArr)
16.实现push
const arr = [1, 2]
Array.prototype.myPush = function (params) {
this[this.length] = params
return this.length
}
arr.myPush(3)
arr.myPush(4)
17.实现filter
const arr = [1, 2, 3, 4, 5]
Array.prototype.myFilter = function (fn) {
const result = []
for (let i = 0; i < this.length; i++) {
fn(this[i]) && result.push(this[i])
}
return result
}
const res = arr.myFilter((e) => e >= 2)
console.log(res)
18.实现map
Array.prototype.myMap = function (fn) {
const result = []
for (let i = 0; i < this.length; i++) {
result.push(fn(this[i]))
}
return result
}
19.实现add(1)(2)(3)(4)
function add(x) {
let num = x
const tmp = function (y) {
num += y
return tmp
}
Function.prototype.toString = function () {
return num
}
return tmp
}
console.log(+add(1)(2))
20.promise异步加载图片
const loadImg = function (url) {
return new Promise((resolve, reject) => {
let img = new Image()
img.src = url
img.onload = () => {
resolve()
}
img.onerror = (err) => {
reject(err)
}
})
}
21.发布订阅模式-简易版
class eventBus {
constructor() {
this.handlers = {}
}
on(type, handler) {
if (!this.handlers[type]) {
this.handlers[type] = []
}
this.handlers[type].push(handler)
}
emit(type, params) {
if (!this.handlers[type]) {
return new Error("事件未注册")
}
this.handlers[type].forEach((element) => {
element(params)
})
}
off(type, handler) {
if (!this.handlers[type]) {
return new Error("事件未注册")
}
const index = this.handlers[type].findIndex((e) => e === handler)
if (index === -1) {
return new Error("不存在该事件")
} else {
this.handlers.splice(index, 1)
}
}
}
22.Object.defineProperty
const obj = {
name: "a",
age: 18,
sex: "man",
}
const p = {}
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
Object.defineProperty(p, key, {
get() {
console.log("读取")
return obj[key]
},
set(val) {
console.log("修改")
obj[key] = val
},
})
}
}
23.proxy
const obj = {
name: "a",
age: 18,
sex: "man",
}
const p = new Proxy(obj, {
get(target, propName) {
console.log("读取", propName)
return Reflect.get(target, propName)
},
set(val) {
console.log("修改", val)
return Reflect.set(target, propName, val)
},
deleteProperty() {
console.log("删除")
return Reflect.defineProperty(target, propName)
},
})
24.实现路由
class Route {
constructor() {
this.Route = {}
this.currentHash = ""
this.freshRoute = this.freshRoute.bind(this)
window.addEventListener("load", this.freshRoute, false)
window.addEventListener("hashchange", this.freshRoute, false)
}
storeRoute(path, cb) {
this.Route[path] = cb || function () {}
}
freshRoute() {
this.currentHash = location.hash.slice(1) || "/"
this.Route[this.currentHash]()
}
}
25.用settimeout实现setInterval
function mySetTimeout(fn, timeout) {
let timer = { flag: true }
function interval() {
if (timer.flag) {
fn()
setTimeout(interval, timeout)
}
}
setTimeout(interval, timeout)
return timer
}
function fn1() {
console.log(1)
}
mySetTimeout(fn1, 1000)
26.setInterval实现setTimeout
function mySetInterval(fn, timeout) {
const timer = setInterval(() => {
fn()
clearInterval(timer)
}, timeout)
}
function fn1() {
console.log(1)
}
mySetInterval(fn1, 1000)
27.实现jsonp
function callback(params) {
console.log(params)
}
function myJsonp(src) {
const script = document.createElement("script")
script.src = src
script.type = "text/javascript"
script.onload = function () {
script.remove()
}
document.body.append(script)
}
const oBtn = document.querySelector(".btn")
oBtn.onclick = function () {
myJsonp()
}
28.获取url的参数并转换成对象
function getQuery() {
let res = {}
const queryStr = window.location.search
const reg = /([^&=?]+)=([^&]+)/g
const found = queryStr.match(reg)
if (found) {
found.map((e) => {
e.split
const arr = e.split("=")
res[arr[0]] = arr[1]
})
}
return res
}
const res = getQuery(url)
console.log(res)
29.数组去重
function myFilter(arr) {
return arr.filter((item, index, arr) => {
return arr.indexOf(item, 0) === index
})
}