手写instanceof
function _instanceof (obj, constructor) {
if(typeof obj !== 'object' || obj === null) return false
let proto = Object.getPrototypeOf(obj)
while (proto) {
if(proto === constructor.prototype) {
return true
}
proto = Object.getPrototypeOf(proto)
}
return false
}
手写深拷贝
function deepClone (obj) {
if(typeof obj !== 'object' || obj === null) return obj
let newObj = Array.isArray(obj) ? [] : {}
for(let key in obj) {
if(obj[key] !== 'object' || obj[key] === null) {
newObj[key] = deepClone(obj[key])
} else {
newObj[key] === obj[key]
}
}
return newObj
}
手写call
Function.prototype.Mycall = function (obj, ...args) {
let context = obj || window
let key = Symbol('key')
obj[key] = this
let res = obj[key](...arg)
delete obj[key]
return res
}
手写防抖节流
// 手写防抖节流
function debounce (time, fn) {
let timer = null
return function (...args) {
let _this = this
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.call(_this,...args)
}, time);
}
}
// 节流
function throttle (time, fn) {
let time = null
let nowTime = 0
return function (...args) {
let _this = this
let currentTime = +new Date()
if(currentTime - nowTime > time) {
fn.call(_this,...args)
nowTime = currentTime
}
}
}
手写继承
// 原型继承
function Parent (name) {
this.name = name
this.likes = ['yellow', 'blue', 'red']
this.hellow = function () {
console.log(`my name is ${this.name}`)
}
}
function Child (name) {
this.name = name
}
Child.prototype = new Parent()
let c = new Child('xiaom')
//
c.hellow()
let c1 = new Child('xiaoh')
console.log(c.likes)
//缺点 c修改了父元素的属性 c1也会变化
c.likes.push('pink')
console.log(c1.likes)
// 构造函数继承
function Parent (name) {
this.name = name
this.likes = ['yellow', 'blue', 'red']
this.hellow = function () {
console.log(`my name is ${this.name}`)
}
}
Parent.prototype.sayLikes = function () {
console.log(`my like color ${this.likes.join(',')}`)
}
function Child (name) {
Parent.call(this)
this.name = name
}
let c = new Child('xiaom')
c.hellow()
// 不会影响其他子类
c.likes.push('pink')
console.log(c.likes)
let c1 = new Child('xiaoh')
console.log(c1.likes)
// 报错 缺点 不能继承父类原型上的属性和方法
c.sayLikes()
// 组合式继承 -- 缺点父类会被调用2次
function Parent (name) {
this.name = name
this.likes = ['yellow', 'blue', 'red']
this.hellow = function () {
console.log(`my name is ${this.name}`)
}
}
Parent.prototype.sayLikes = function () {
console.log(`my like color ${this.likes.join(',')}`)
}
function Child (name) {
Parent.call(this)
this.name = name
}
Child.prototype = new Parent()
let c = new Child('xiaom')
c.hellow()
// 不会影响其他子类
c.likes.push('pink')
console.log(c.likes)
let c1 = new Child('xiaoh')
console.log(c1.likes)
c.sayLikes()
// 组合寄生式继承
function Parent (name) {
this.name = name
this.likes = ['yellow', 'blue', 'red']
this.hellow = function () {
console.log(`my name is ${this.name}`)
}
}
Parent.prototype.sayLikes = function () {
console.log(`my like color ${this.likes.join(',')}`)
}
function Child (name) {
Parent.call(this)
this.name = name
}
Child.prototype = Object.create(Parent.prototype)
Child.constructor = Child
let c = new Child('xiaom')
c.hellow()
// 不会影响其他子类
c.likes.push('pink')
console.log(c.likes)
let c1 = new Child('xiaoh')
console.log(c1.likes)
c.sayLikes()
// class类继承
class Parent {
constructor (name) {
this.name = name
}
say = function () {
console.log(`my name is ${this.name}`)
}
}
class Child extends Parent {
constructor (name) {
super(name)
this.name = name
}
}
let c = new Child('xiaom')
c.say()
手写new
// 手写new操作符
function _new (fn, ...args) {
// 定义一个空对象
let obj = {}
// 空对象的__proto__ = 构造函数的prototype
obj.__proto__ = fn.prototype
// 执行构造函数 将新创建的对象作为构造函数的执行上下文
let res = fn.call(obj, ...args)
// 如果构造函数的返回值是一个对象则返回这个对象否则返回新创建的对象
return (typeof res !== 'object' || res === null) ? obj : res
}
手写promise
class MPromise {
constructor(fn) {
this.val = ''
this.reson = ''
this.status = 'pending'
this.onFulfilledCallback = []
this.onRejectedCallback = []
try {
fn(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(val){
if(this.status === 'pending') {
this.status = 'fulfilled'
this.val = val
this.onFulfilledCallback.forEach(item => item());
}
}
reject (reson){
if(this.status === 'pending') {
this.status = 'rejected'
this.reson = reson
this.onRejectedCallback.forEach(item => item());
}
}
then (onFulfilled, onRejected) {
let p = new MPromise((resolve, reject)=>{
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : ()=>{}
onRejected = typeof onRejected === 'function' ? onRejected : ()=>{}
if(this.status === 'rejected'){
setTimeout(() => {
try {
let x = this.onRejected(this.reson)
this.resolvePromise(p, x,resolve, reject)
} catch (error) {
this.reject(error)
}
});
}
if(this.status === 'fulfilled'){
setTimeout(() => {
try {
let x = this.onFulfilled(this.val)
this.resolvePromise(p, x,resolve, reject)
} catch (error) {
this.reject(error)
}
});
}
if(this.status === 'pending') {
this.onFulfilledCallback.push(()=>{
setTimeout(() => {
try {
let x = onFulfilled(this.val)
this.resolvePromise(p, x,resolve, reject)
} catch (error) {
this.reject(error)
}
});
})
this.onRejectedCallback.push(()=>{
setTimeout(() => {
try {
let x = onRejected(this.reson)
this.resolvePromise(p, x,resolve, reject)
} catch (error) {
this.reject(error)
}
});
})
}
})
return p
}
resolvePromise (p,x,resolve,reject) {
// 如果p和x相同报错
if(p === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if(x !== null && (typeof x==='object' || typeof x==='function')){
try {
let then = x.then
if(typeof then ==='function') {
then.call(x, y=>{
resolvePromise(p, y, resolve, reject);
},r =>{
reject(r)
})
}else{
resolve(x)
}
} catch (error) {
reject(error)
}
}else[
resolve(x)
]
}
catch (onRejected) {
onRejected = typeof onRejected === 'function' ? onRejected : ()=>{}
return this.then(undefined, onRejected)
}
static all (promises) {
let result = []
let index
return new MPromise((resolve, reject)=>{
function addData(key, value) {
result[key] = value
index++
if(index === array.length) {
resolve(result)
}
}
for(let i = 0; i < promises.length; i++) {
let current = promises[i]
if(current instanceof MPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, promises[i])
}
}
})
}
static race (promises) {
return new MPromise((resolve, reject)=>{
for(let i = 0; i < promises.length; i++) {
let current = promises[i]
if(current instanceof MPromise) {
current.then(value => resolve(value), reason => reject(reason))
} else {
resolve(current)
}
}
})
}
static any (promises) {
let result = []
let index
return new MPromise((resolve, reject)=>{
function addData(key, value) {
result[key] = value
index++
if(index === array.length) {
reject(result)
}
}
for(let i = 0; i < promises.length; i++) {
let current = promises[i]
if(current instanceof MPromise) {
current.then(value => resolve(value), reason => addData(i, reason))
} else {
resolve(promises[i])
}
}
})
}
static allSettled () {
let result = []
let index
return new MPromise((resolve, reject)=>{
function addData(key, value) {
result[key] = value
index++
if(index === array.length) {
resolve(result)
}
}
for(let i = 0; i < promises.length; i++) {
let current = promises[i]
if(current instanceof MPromise) {
current.then(value => addData(i, value), reason => addData(i, reason))
} else {
addData(i, promises[i])
}
}
})
}
finally (callback) {
return this.then((val)=>{
return MPromise.resolve(callback()).then(()=>val)
},(reason)=>{
return MPromise.reject(callback()).then(()=>{ throw reason})
})
}
static resolve(value) {
if(value instanceof MPromise) return value
return new MPromise(resolve => resolve(value))
}
static reject(reason) {
return new MPromise((resolve, reject) => reject(value))
}
}
手写一个单例
// 手写一个单例
class Single{
constructor () {
this.instance = null
}
static getInstance = (...args) => {
if(!this.instance) {
this.instance = new Single(...args)
}
return this.instance
}
}
手写一个发布订阅
class eventEmit {
constructor() {
this.events = {}
}
on (key, fn, isOnce) {
if(this.events.hasOwnProperty(key)){
this.events[key].push({fn, isOnce})
} else {
this.events[key] = [{fn, isOnce}]
}
}
once (key, fn) {
this.on(key, fn, true)
}
off(key, fn){
if(!fn){
this.events[key] = []
} else{
if(this.events.hasOwnProperty(key)){
this.events[key] = this.events[key].filter((item) => item.fn === fn)
}
}
}
emit (key, ...args) {
if(this.events.hasOwnProperty(key)){
this.events[key] = this.events[key].filter((item) => {
item.fn(...args)
return !item.isOnce
})
}
}
}
手写一个观察者
// 手写观察者
// 被观察者
class Student {
constructor(name, status) {
this.name = name
this.observes = []
this.status = status
}
// 添加观察者
addObserve (obj) {
this.observes.push(obj)
}
// 移除观察者
removeObserve (obj) {
this.observes = this.observes.filter((item) => item !== obj)
}
updateStatus (status) {
this.observes.forEach(item => {
item.notify(this.name, this.status, status)
})
this.status = status
}
}
class Observer {
constructor(name) {
this.name = name
}
// 通知
notify (name, status, newStatus) {
console.log(`${this.name} 您好 ${name} 的状态由是 ${status} 变为 ${newStatus}`)
}
}
let s = new Student('小明', 'happay')
let t = new Observer('小明老师')
let p = new Observer('小明爸爸')
s.addObserve(t)
s.addObserve(p)
s.updateStatus('bad')
手写一个常用的loader
// 手写一个常用的loader
module.exports = function (countent) {
// loader 分为 pre normal inline post loader 执行顺序从下往上 从右往左
// loader 有同步 异步 和 row
// 可以做一些操作 例如 style-loader
let str = `
let style = document.createElement('style')
style.innerHTML = ${JSON.stringify(content)}
document.head.appendChild(style)
`
return str
}
手写一个常用的plugin
// 手写一个常用的plugin
class AnalyzeWbpackPlugin {
constructor(parameters) {
}
apply (compiler) {
let str = `| fileName | size |
| --- | --- |`
compiler.hooks.emit.tap('AnalyzeWbpackPlugin', (compliactiong)=>{
const arr = []
Object.keys(compliactiong.assets).forEach((fileName)=>{
const file = compliactiong.assets[fileName]
const obj = {fileName, size: Math.ceil(file.size() / 1024)}
arr.push(obj)
})
arr.sort((a,b) => {
return b.size - a.size
})
arr.forEach((item) => {
let {fileName, size} = item
let s = `| ${fileName} | ${size}kb |`
str += s + '\n'
})
compliactiong.assets['analyze.md'] = {
source(){
return str
},
size () {
return str.length
}
}
})
}
}
moudle.exports = AnalyzeWbpackPlugin
手写一个基本的webpack配置
const {reslove} = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = function () {
return {
entry: reslove(__dirname, '../src/main.js'),
output: {
path: reslove(__dirname, '../dist'),
fileName: "static/js/[name].[fullhash:8].js",
clear: true
},
module: {
rules: [
{
test: /\.(js)$/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(css|less)$/,
use: {
loader: "style-loader",
loader: "css-loader",
loader: "postcss-loader",
loader: "less-loader"
}
},
{
test: /\.(png|jpeg|jpg|gif|webp|svg)$/,
generator: {
filename: "static/images/[name].[contenthash:8][ext]"
}
}
]
},
plugin:[
new HtmlWebpackPlugin({
template: reslove(__dirname, "../public/index.html"),
inject: true
})
]
}
}