冒泡排序
function fn(arr) {
for(let i=0
for(let j=0
if(arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
}
return arr
}
非原地快排
function quickSort(arr) {
if(arr.length <= 1) return arr
let arr1 = [], arr2 = [], p = arr[0]
for(let i=1;i<arr.length;i++) {
if(arr[i] < p) {
arr1.push(arr[i])
} else {
arr2.push(arr[i])
}
}
let res = [...quickSort(arr1), p, ...quickSort(arr2)]
}
工厂模式
function Product(name) {
this.name = name;
}
Product.prototype.init = function () {
console.log('init');
}
Product.prototype.go = function () {
console.log('go');
}
function Factory () {
}
Factory.prototype.add = function(name) {
return new Product(name);
}
let f = new Factory();
let a = f.add('a');
console.log(a.name);
a.init();
a.go();
发布订阅模式
class Event {
constructor() {
this.listener = {
}
}
on(name, cb) {
if(!this.listener[name]) {
this.listener[name] = []
}
this.listener[name].push(cb)
}
emit(name) {
for(let key of this.listener[name]) {
key()
}
}
}
单例模式
class singleDog {
static getInstance() {
if(!singleDog.instance) {
singleDog.instance = new singleDog()
}
return singleDog.instance
}
}
instanceof
function instanceOf(obj, Constructor) {
let proto = obj.__proto__
while (proto !== Constructor.prototype) {
if(proto === null) return false
proto = proto.__proto__
}
return true
}
防抖
function debounce(fn) {
let timeout = null;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, 500);
};
}
function sayHi() {
console.log('防抖成功');
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi));
节流
function throttle(fn) {
let canRun = true;
return function () {
if (!canRun) return;
canRun = false;
setTimeout(() => {
fn.apply(this, arguments);
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log(e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi));
call
Function.prototype.mycall = function(context) {
if(typeof this !== 'function') {
throw new Error('error')
}
context = context || window
let args = [...arguments].slice(1)
context.fn = this
const res = context.fn(...args)
delete context.fn
return res
}
apply
Function.prototype.apply = function(context) {
if(typeof this !== 'function') {
throw new Error('error')
}
context = context || window
context.fn = this
let res
if(arguments[1]) {
res = context.fn(...arguments[1])
}else {
res = context.fn()
}
delete context.fn
return res
}
完整且简洁bind
Function.prototype.mybind = function(context) {
if(typeof this !== 'function') {
throw new Error('error')
}
const _this = this
const args = [...arguments].slice(1)
return function F(){
if(_this instanceof F) {
return new _this(...args,...argument)
}
return _this.apply(context,args.concat(argument))
}
}
bind
简单bind
Function.prototype.mybind = function(THIS,...arg1) {
let fn = this
return function(...arg2) {
return fn.call(THIS,...arg1,...arg2)
}
}
function sum(a,b,c) {
return a + b + c
}
let sum10 = sum.bind(null,10)
console.log(sum10(20,30));
进阶bind
Function.prototype.mybind = function(THIS,...arg1) {
let fn = this
function T(...arg2) {
return fn.call(THIS,...arg1,...arg2)
}
T.prototype = Object.create(fn.prototype)
return T
}
function sum(a,b,c) {
return a + b + c
}
let sum10 = sum.bind(null,10)
console.log(sum10(20,30));
bind完成版
Function.prototype.mybind = function(THIS,...arg1) {
let fn = this
function T(...arg2) {
return fn.call(this instanceof T ? this : THIS,...arg1,...arg2)
}
T.prototype = Object.create(fn.prototype)
return T
}
function sum(a,b,c) {
return a + b + c
}
let sum10 = sum.bind(null,10)
console.log(sum10(20,30));
new
function myNew(fn, ...args) {
let obj ={}
obj = Object.create(fn.prototype)
let res = fn.apply(obj, args)
return res instanceof Object ? res : obj
}
Object.create
function create(o) {
let obj = {}
Object.setPrototypeOf(obj, o)
return obj
}
sleep
function sleep(t) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},t)
})
}
await sleep(1000)
遍历DOM树
function Tree() {
var Node = function(key){
this.key = key;
this.left = null;
this.right = null;
}
root =null;
前序遍历
Tree.prototype.preOrderTraverse = function(callback){
preOrder(root, callback);
}
var preOrder = function(node,callback){
if(node !== null){
callback(node.key);
preOrder(node.left, callback);
preOrder(node.right, callback);
}
}
promise
function MyPromise(fn) {
let self = this
self.value = null
function onResolve(value) {
console.log(value);
self.value = value
}
function onReject(reason) {}
fn(onResolve, onReject)
}
MyPromise.prototype.then = function(fn) {
fn(this.value)
}
new MyPromise((resolve,reject) => {
resolve(1000)
})
.then(r => {
console.log(r);
})
更完整的promise
function MyPromise(fn) {
let self = this;
this.value = undefined;
this.status = 'PENDING';
function onResolve(value) {
self.status = 'FULFILLED';
self.value = value;
self.onFulFilled && self.onFulFilled(value);
}
function onReject(reason) {}
fn(onResolve, onReject);
}
MyPromise.prototype.then = function(fn) {
if (this.status === 'FULFILLED') fn(this.value);
else if (this.status === 'PENDING') this.onFulFilled = fn;
}
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1000);
}, 1000)
})
.then(r => {
console.log(r)
})
function readFile(fn) {
fn('hello world')
}
readFile((r) => {
console.log(r);
})
promise.all
Promise.myAll = function(promiseArr) {
return mewPromise((resolve, reject) => {
let res = [], count = 0
for(let i = 0;i < promiseArr.length; i++) {
promiseArr[i].then((r) => {
res[i] = r
count++
if(count === promiseArr.length) {
resolve(res)
}
})
.catch(() => {
reject()
})
}
})
}
promise 限制并发
Promise.limitAll = function (promiseCreators, max) {
let i = 0, count = 0, pending = 0, res = [];
return new Promise((resolve, reject) => {
function requestWork() {
if (count >= promiseCreators.length) {
resolve(res);
return;
}
while (pending < max && i < promiseCreators.length) {
const creator = promiseCreators[i];
let index = i;
creator().then((r) => {
console.log(r);
pending--;
count++;
res[index] = r;
requestWork();
})
i++;
pending++;
}
}
requestWork();
})
}
深度遍历
let deepTraversal1 = (node, nodeList = []) => {
if (node !== null) {
nodeList.push(node)
let children = node.children
for (let i = 0; i < children.length; i++) {
deepTraversal1(children[i], nodeList)
}
}
return nodeList
}
广度遍历
let widthTraversal2 = (node) => {
let nodes = []
let stack = []
if (node) {
stack.push(node)
while (stack.length) {
let item = stack.shift()
let children = item.children
nodes.push(item)
for (let i = 0; i < children.length; i++) {
stack.push(children[i])
}
}
}
return nodes
}
原地快排
const quickSort = (arr, i, j) => {
if(i >= j) return;
let left = i, right = j, base = arr[left];
while(left < right){
while(arr[right] >= base && left < right){
right --;
}
arr[left] = arr[right];
while (arr[left] <= base && right > left){
left ++;
}
arr[right] = arr[left];
}
arr[left] = base;
quickSort(arr, i, left-1);
quickSort(arr, left+1, j);
}
quickSort(arr,0,arr.length-1)
defineProperty
var data = {
name: 'yuanlong'
}
observe(data)
let name = data.name
data.name = 'jinlong'
function observe(obj) {
Object.keys(obj).forEach(key => {
definReactive(obj,key,obj[key])
})
}
function definReactive(obj, key, val) {
if(typeof val === 'object' && val !== null) {
observe(val)
}
Object.defineProperty(obj,key, {
get: function() {
return val
},
set: function(newVal) {
val = newVal
}
})
}
柯里化
function curry(fn) {
let len = fn.length, args = [];
function T(...arg) {
args = args.concat(arg);
if (args.length >= len) {
let res = fn(...args);
args = [];
return res;
} else {
return T;
}
}
return T;
}
function curry(fn) {
let allArgs = []
return function next(arguments) {
if(arguments) {
allArgs = allArgs.concat(arguments)
return next
} else {
fn.apply(null, allArgs)
}
}
}
深拷贝
function deepClone(obj) {
var newObj = obj instanceof Array ? [] : {};
if (newObj instanceof Array) {
obj.forEach((v, i) => {
newObj[i] = typeof obj[i] === 'object' ? deepClone(v) : v
})
} else {
for (var item in obj) {
newObj[item] = typeof obj[item] == 'object' ? deepClone(obj[item]) : obj[item]
}
}
return newObj;
}
寄生组合继承
<script>
function Parent(name) {
this.name = name
}
Parent.prototype.sayName = () => {
console.log(this.name);
}
function Son(age) {
this.age = age
Parent.call(this)
}
Son.prototype.sayAge = () => {
console.log(this.age);
}
Son.prototype = Object.create(Parent.prototype)
</script>
手写reduce
Array.prototype.myReduce = function(fn, init = this[0]) {
for(let i=0;i<this.length;i++) {
let current = this[i]
init = fn(init, current, i, this)
}
return init
}
let myres = arr.myReduce((pre, current,index, arr)=>{
console.log(pre, current, index, arr);
return pre += current
}, 0)
console.log(myres);