必背js代码
深拷贝
function deepClone(oldobj) {
if (typeof oldobj !== "object" || oldobj == null) {
return oldobj;
}
let reslut;
if (oldobj instanceof Array) {
reslut = [];
} else {
reslut = {};
}
for (let key in oldobj) {
if (oldobj.hasOwnProperty(key)) {
reslut[key] = deepClone(oldobj[key]);
}
}
return reslut;
}
发布订阅
function Dep() {
this.subs = [];
}
Dep.prototype = {
addSub(sub) {
this.subs.push(sub);
},
notify() {
this.subs.forEach(sub => sub.update());
}
};
function Watcher(fn) {
this.fn = fn;
}
Watcher.prototype.update = function() {
this.fn();
};
let watcher = new Watcher(() => console.log(111));
let dep = new Dep();
dep.addSub(watcher);
dep.addSub(watcher);
dep.notify();
实现eventbus
function Event() {
this.cache = {};
}
Event.prototype.on = function(type, handle) {
if(!this.cache[type]) {
this.cache[type] = [handle];
}else {
this.cache[type].push(handle);
}
}
Event.prototype.emmit = function() {
var type = arguments[0];
var arg = [].slice.call(arguments, 1);
for(var i = 0; i < this.cache[type].length; i++) {
this.cache[type][i].apply(this, arg);
}
}
Event.prototype.empty = function(type) {
this.cache[type] = [];
}
Event.prototype.remove = function(type, handle) {
this.cache[type] = this.cache[type].filter(function(ele) {
return ele != handle;
})
}
Event.prototype.once = function(type, handle) {
if(!this.cache[type]) {
this.cache[type] = [];
}
handle.tag = 'true';
this.cache[type].push(handle);
}
function deal1(time) {
console.log('overtime1:' + time);
}
function deal2(time) {
console.log('overtime2:' + time);
}
var oE = new Event();
oE.on('over', deal1);
oE.on('over', deal2);
oE.emmit('over', '2018-9-25');
oE.remove('over', deal2);
oE.emmit('over', 'seconde-1-1');
数组拍平
function fn(arr) {
let arr1 = [];
arr.forEach((val) => {
if (val instanceof Array) {
arr1 = arr1.concat(fn(val));
} else {
arr1.push(val);
}
});
return arr1;
}
节流
function throttle(fn, delay) {
let timer = null;
return function(){
if(timer){
return ;
}else{
timer = setTimeOut(() => {
fn();
timer = null;
},delay)
}
}
}
防抖
function debounce(fn, delay){
let timer = null;
return function(){
if(timer){
clearTimeout(timer)
}else{
timer = setTimeOut(() => {
fn();
},delay)
}
}
}
instanceof实现
function myinstanceof(left, right){
if(! typeof left == 'object' || left == null){
return false;
}
while(true){
if(left === null){
return false;
}else{
left.__proto__ = right.prototype;
return true;
left = left.__proto__;
}
}
}
手写Promise
class Mypromise {
static PENDING = "待定";
static FULFILLE = "成功";
static REJECTED = "失败";
constructor() {
this.status = Mypromise.PENDING;
this.reslut = null;
this.resloveCallbacks = [];
this.rejectCallbacks = [];
}
reslove(result){
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.FULFILLE;
this.result = result;
this.resloveCallbacks.forEach((callback) => {
callback(result);
});
}
}
reject(result){
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.REJECTED;
this.result = result;
this.rejectCallbacks.forEach((callback) => {
callback(result);
});
}
}
then(onFULFILLED, onREJECTED){
return new MyPromise((resolve, reject) => {
onFULFILLED = typeof onFULFILLE === "function" ? onFULFILLED : () => {};
onREJECTED = typeof onFULFILLE === "function" ? onREJECTED : () => {};
if (this.status === MyPromise.PENDING) {
this.rejectCallbacks.push(onREJECTED);
this.resloveCallbacks.push(onFULFILLED);
}
if (this.status === MyPromise.FULFILLE) {
setTimeout(() => {
onFULFILLED(this.result);
});
}
if (this.status === MyPromise.REJECTED) {
setTimeout(() => {
onREJECTED(this.result);
});
}
});
}
}
手写promise.all
function promiseAll(promiseArray) {
return new Promise((resolve,reject) => {
if(!Array.isArray(promiseArray)){
return reject(new Error("错误"));
}
const len = promiseArray.length;
let res = [];
let counter = 0;
for(let i = 0; i < len; i ++){
Promise().resolve(promiseArray[i])
.then(value => {
counter ++;
res[i] = value;
if(counter === len){
reslove(res);
}
})
.catch(e => {
reject(e);
}
}
})
}
手写new
function myNew(fn,...arg) {
let obj = {};
obj.__proto__ = fn.prototype;
let res = fn.apply(this,arg);
return res instanceof Object ? res : obj;
}
简单实现响应式函数,对一个对象内的所有的key添加响应式特性?
const render = (key, val) => {
console.log(`set key = ${key} vale = ${val}`);
};
const defineReactive = (obj, key, val) => {
if (typeof obj === "object") {
for (const key in obj) {
defineReactive(obj, key, obj[key]);
}
}
Object.defineProperty(obj, key, {
get() {
return val;
},
set(newVale) {
if (val === newVale) {
return;
}
val = newVale;
render(key, val);
},
});
};
const data = {
a: 1,
b: 2,
c: {
c1: {
af: 999,
},
c2: 4,
},
};
reactive(data);
data.a = 5;
data.b = 7;
data.c.c2 = 4;
data.c.c1.af = 121;
括号匹配
function isValid(str){
let strArr = str.split(''),
left = [];
for(let i=0;i<strArr.length;i++){
if(strArr[i] == '(' || strArr[i] == '[' || strArr[i] == '{'){
left.push(strArr[i])
}else{
if(strArr[i] == ')' && left.pop() != '('){
return false
}
if(strArr[i] == ']' && left.pop() != '['){
return false
}
if(strArr[i] == '}' && left.pop() != '{'){
return false
}
}
}
return left.length == 0
}
let test = '{9()32358}'
console.log(isValid(test))
请简单实现双向数据绑定mvvm
<input type="text" id="input">
const data = {};
const input = document.getElementById("input");
Object.defineProperty(data, "text", {
set(value) {
input.value = value;
this.value = value;
}
})
input.onchange = function(e) {
data.text = e.target.value;
}
虚拟dom转真实dom
function _render(vNode) {
if (typeof vNode === "number") {
vNode = String(vNode);
}
if (typeof vNode === "string") {
return document.createTextNode(vNode);
}
const dom = document.createElement(vNode.tag);
if (vNode.attrs) {
Object.keys(vNode.attrs).forEach((key) => {
const value = vNode.attrs[key];
dom.setAttribute(key, value);
});
}
vNode.children.forEach((child) => {
dom.appendChildren(_render(child));
return dom;
});
}
遍历DOM节点
function traversalDom(element, callback) {
callback(element);
element = element.firstElementChild;
while (element) {
traversalDom(element, callback);
element = element.nextElementSibling;
}
}
const subTree = document.getElementById("content");
const callback = (subTree) => {
console.log(
element.innerText,
element.tagName,
"子元素的个数:",
element.childElementCount
);
};
traversalDom(subTree, callback);
简单轮询
function setTimer () {
let timer;
axios.post(url, params)
.then(function (res) {
if(res){
console.log(res);
timer = setTimeout(() => {
this.setTimer()
}, 5000)
}else {
clearTimeout(timer)
}
})
.catch(function (error) {
console.log(error);
});
},
手写Promise.finally
Promise.finally = function (callback) {
return this.then(data => {
return Promise.resolve(callback()).then(value => {
return value;
})
}, err => {
return Promise.reject(callback()).then(err => {
throw err;
})
})
}
手写Promise.race
Promise.race = function (promises) {
return new Promise((resolve, rejected) => {
promises = Array.from(promises);
if (promises.length == 0)
return resolve([]);
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then(data => {
resolve(data);
return;
}, err => {
reject(err);
return;
})
}
})
}
冒泡排序
function bubbleSort(arr) {
let len = arr.length;
for(let i = 0; i < len; i ++){
for(let j = 0; j < len - 1 - i; j ++)
if(arr[j] > arr[j + 1]){
let temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
return arr;
}
快速排序
def quick_sort(data):
"""快速排序"""
if len(data) >= 2:
mid = data[len(data)//2]
left, right = [], []
data.remove(mid)
for num in data:
if num >= mid:
right.append(num)
else:
left.append(num)
return quick_sort(left) + [mid] + quick_sort(right)
else:
return data
选择排序
function selectionSort(arr) {
var len = arr.length;
var minIndex, temp;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
插入排序
function insertionSort(arr) {
var len = arr.length;
var preIndex, current;
for (var i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i];
while(preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex+1] = arr[preIndex];
preIndex--;
}
arr[preIndex+1] = current;
}
return arr;
}
二叉树层次遍历
var levelOrder = function (root) {
if (!root) return [];
let res = [];
let queue = [];
queue.push(root);
while (queue.length) {
let level = [];
let size = queue.length;
for (let i = 0; i < size; i++) {
let node = queue.shift();
level.push(node.val);
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
res.push(level);
}
return res;
};
二叉树非递归遍历
function vist(p) {
console.log(p.data);
}
var inorderTraversal = function(root) {
if (!root) return [];
const stack = [];
let cur = root;
const res = [];
while (stack.length || cur) {
while (cur) {
stack.push(cur);
cur = cur.left;
}
const node = stack.pop();
res.push(node.val);
if (node.right != null) {
cur = node.right;
}
}
return res;
};
function preOrder(T) {
let p = T;
let stack = [];
while (p || stack.length) {
if (p) {
vist(p);
stack.push(p.data);
p = p.left;
} else {
p = stack.pop();
p = p.right;
}
}
}
function postOrder(T) {
let p = T;
let stack = [];
let r = null;
while (p || stack.length) {
if (p) {
stack.push(p.data);
p = p.left;
} else {
let node = stack.slice(-1);
if(!node.right && !node.right == r){
p = p.right;
}else{
p = stack.pop();
vist(p);
r = p;
p = null;
}
}
}
}
二叉树镜像
var mirrorTree = function(root) {
if (root === null) {
return null;
}
const left = mirrorTree(root.left);
const right = mirrorTree(root.right);
root.left = right;
root.right = left;
return root;
};
二叉树最右边
var rightSideView = function (root) {
if (!root) {
return [];
}
const queue = [root];
const res = [];
while (queue.length) {
let size = queue.length;
for (i = 0; i < size; i++) {
let node = queue.shift();
if (i === size - 1) {
res.push(node.val);
}
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
}
return res;
};
N叉树层次遍历
var levelOrder = function(root) {
if(!root) return [];
let res = [];
let queue = [];
queue.push(root);
while(queue.length){
let size = queue.length;
let level = [];
while(size--){
let node = queue.shift();
level.push(node.val);
for(let child of node.children){
if(child){
queue.push(child);
}
}
}
res.push(level);
}
return res;
};
解析url 拆分出协议 域名 uri 参数
let url = "http://www.runoob.com/index.php?id=1&image=awesome.jpg"
let vars = url.split("&");
let a = []
for(let s in vars){
a.push(vars[s].split("=")[1])
}
console.log(a)
反转链表
const reverseList = head => {
let [pre, cur] = [null, head];
let temp;
while (cur) {
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
};
合并两个有序链表
var mergeTwoLists = function (l1, l2) {
const prehead = new ListNode(-1);
let prev = prehead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
} else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
prev.next = l1 === null ? l2 : l1;
return prehead.next;
};
原型链继承
Grand.prototype.lastName = 'JC';
function Grand() {};
var grand = new Grand();
Father.prototype = grand;
function Father() {
this.name = 'hehe';
}
var father = new Father();
Son.prototype = father;
function Son() {};
var son = new Son();
构造函数继承
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name, age, sex, grade) { Person.call(this, name, age, sex);
this.grade = grade;
}
var student = new Student('dg', 40, 'male', 18);
共享原型
Father.prototype.lastName = 'Deng';
function Father() {};
function Son() {};
Son.prototype = Father.prototype;
var son = new Son();
var father = new Father();
三数之和
var threeSum = function(nums) {
let len = nums.length
if(len<3) return []
let res = []
nums.sort((a,b)=>a-b)
for(let i=0;i<len-2;i++){
let left = i+1
let right = len-1
while(left<right){
let sum = nums[i]+nums[left]+nums[right]
if(sum>0){
right--
}else if(sum<0){
left++
}else{
res.push(`${nums[i]},${nums[left]},${nums[right]}`)
left++
right--
}
}
}
return [...new Set(res)].map(item=>item.split(','))
};