-
(1) 冒泡排序
function sort1(arr) { // 每次都选出一个最大的 const len = arr.length; for(let i = 0; i < len; i++) { for(let j = 0; j< len - i; j++) { if(arr[j] > arr[j+1]){ let temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; }
-
(2) 选择排序
// 选择排序
function sort2(arr) {
const len = arr.length;
for(let i = 0; i < len; i++) {
let k = i; // 记录这个位置
// 每一趟找出最小的数的位置
for(let j = i+1; j < len; j++) {
k = arr[j] < arr[k]? j: k;
}
// 如果位置改变的话
if(k != i) {
let temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
return arr;
}
- (3) 插入排序
// 插入排序:找到每个元素的正确位置。
// 从第二个元素开始,找到其正确的位置(只要前面的元素大于自己,前面的元素就向后移一位)
function sort3(arr) {
const len = arr.length;
for(let i = 1; i < len; i++) {
let cur = arr[i];// 保存当前的元素
let preIndex = i - 1;
// 只要当前的元素小于前面的元素,就将前面的元素后移一位,并且preIndex指针--
while(preIndex>=0 && cur < arr[preIndex]){
arr[preIndex+1] = arr[preIndex];
preIndex --;
}
// 最后要将pre+1的位置换成cur
arr[preIndex + 1] = cur;
}
return arr;
}
- (4) 快排
function quickSort(arr, left, right) {
if(left < right) {
let pos = left - 1;
for(let i = left; i <= right; i++) {
let pivot = arr[right]; // 选取最后一个数作为基数
if(arr[i] <= pivot) {// //若小于等于基准数,pos++,并置换元素, 这里使用小于等于而不是小于, 其实是为了避免因为重复数据而进入死循环
pos++;
let temp = arr[pos];
arr[pos] = arr[i];
arr[i] = temp;
}
}
quickSort(arr, left, pos-1);
quickSort(arr, pos+1, right);
}
return arr;
}
- (5) 实现单链表
// 链表节点类型
function Node (data) {
this.data = data;
this.next = null;
}
// 链表引用类型
function List() {
// 头结点
this.head = new Node();
this.size = 0;
}
List.prototype = {
// 在链表尾部添加节点
add: function(data) {
var current = this.head;
while(current.next != null){
current = current.next;
}
current.next = new Node(data);
this.size++;
},
// 在pos位置插入data
insert: function(pos,data) {
if(pos < 0 || pos > this.size-1) return null;
var last = this.head;
for(var i = 0;i< pos;i++){
last = last.next;
}
// 保存下一个结点
var next = last.next;
last.next = new Node(data);
last.next.next = next;
this.size++;
return data;
}
}
- (6) apply的实现
Function.prototype.myApply = function (obj) {
obj = obj || window ; // 保存this的指向
obj.fn = this; // 添加一个属性为调用apply的函数
let result;
if(arguments[1]) {// 如果存在第一个参数
result = obj.fn(...arguments[1]);
}else{
result = obj.fn();
}
delete obj.fn // 删除这个属性
return result;
}
- (7) call 的实现
Function.prototype.myCall = function(obj) {
obj = obj || window;
obj.fn = this;
let args = [...arguments].slice(1); // 截取第一个参数之后的
let result = obj.fn(...args);
delete obj.fn;
return result;
}
- (8) bind的实现
Function.prototype.myBind = function(obj) {
if( typeof this !== 'function') {
throw new Error('is not a function');
}
let fn = this; // 保存这个函数
let args = [...arguments].slice(1);
let fBound = function() {
// 如果是new绑定,则this指向为fBound的实例对象。
return fn.apply( this instanceof fBound? this: obj ,[...arguments].concat(args) )
}
// 如果是new绑定,就要考虑对原型链的影响。
function tmp () {};
tmp.prototype = this.prototype;
fBound.prototype = new tmp();
// 上面的操作就相当于 fBound.prototype = this.prototype;
return fBound;
}
- (9) new的实现
function myNew() {
// 创建一个对象
let obj = Object.create(null);
// 获取构造函数
let constructor = [...arguments][0];
// 连接原型
obj.__proto__ = constructor.prototype;
// 绑定this
let result = constructor.apply(obj, [...arguments].slice(1));
// 判断返回的结果是否为一个对象
return typeof result === 'object'? result: obj;
}
// let obj = myNew(Preson,"xiaoqi");
-
(10) 实现继承(寄生组合式)
function Person(name) { this.name = name; } Person.prototype.getName = function() { console.log(this.name); } function Child(age,name) { Person.call(this, name); // 借助构造函数 this.age = age; } // 避免两次调用Person的构造函数 // 核心:用一个空F构造函数,去取代执行Person这个构造函数。 function create (proto) { function F () {}; F.prototype = proto; return new F(); } Child.prototype = create(Person.prototype); Child.prototype.constructor = Child; Child.prototype.say = function() { console.log(this.age); } let child = new Child(20, 'xiaoqi'); child.getName(); child.say();
-
(11) Object.create
function create(proto) { function F () {}; F.prototype = proto; return new F(); }
-
(12) 实现一个Curry函数
let curry = (fn, ...args) => {
return args.length < fn.length
? (...newArgs) => curry(fn, ...args,...newArgs)
: fn(...args);
}
function add(a, b, c) {
return a*b*c;
}
let multi = curry(add, 1);
console.log(multi(2)(3)); // 6
-
(13) 实现一个深拷贝
var newObj = JSON.parse(JSON.stringify(obj)); // 简单版 function deepClone(obj) { // 如果不是对象直接返回 if( typeof obj !== 'object') return ; let newObj = new obj.constructor(); // 数组或者对象 for(let key in obj){ if(obj.hasOwnProperty(key)){ newObj[key] = typeof obj[key] === 'object'? deepClone(obj[key]) : obj[key]; } } return newObj; }
-
(14) 实现一个instanceof
function instanceOf (left ,right) { let lPro = left.__proto__; let rPro = right.prototype; while(true) { if(lPro === rPro) return true; if(lPro === null) return false; lPro = lPro.__proto__; } }
-
(15) 实现防抖
function debounce (fn, wait = 50) { let timer = null; return (...args) => { // 如果存在定时器,清除定时器, 最终只执行一次 if(timer) clearTimeout(timer); temer = setTimeout(() => { fn.apply( this, args); }, wait); } }
-
(16) 实现一个节流
function throttle(fn, wait) { let timer = null; return (...args){ if(!timer) { timer = setTimeout( ()=>{ fn.apply(this, args); clearTimeout(timer); timer = null; },wait) } } }
-
(17) 数组扁平
function flat1(array) { return array.reduce((pre, cur)=>{ return pre.concat(Array.isArray(cur)? flat(cur):cur); },[]) } function flat2(array) { let res = []; array.map((item)=>{ if(Array.isArray(item)){ res = res.concat(flat2(item)) }else { res.push(item) } }); return res; } function flat3(array) { while (array.some(Array.isArray)) { array = [].concat(...array); } return array; }
-
(18) 数组去重
es6去重:
const myArray = [1,1,2,2,3,3,4,4,5,5] console.log([...new Set(myArray )]);// [1, 2, 3, 4, 5]
es5去重:
function fn(arr) { let obj = {}; arr.forEach((item) => { obj[item] = ''; }) return Object.keys(obj); }
-
(19) 手写jsonp
<script>
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'url?user=admin&callback=cb';
function cb(res) {
alert(JSON.stringify(res));
}
</script>
// 后端实现
var qs = require('qs');
var http = require('http');
var server = http.createServer();
server.on("request", function(req, res) {
var params = qs.parse(req.url.split("?")[1]);
var fn = params.callback;
res.write(fn + '(' + JSON.stringify({"status": true, "user": "admin"})+ ')');
res.end();
})
server.listen(8081);
- (20) 实现原生ajax
let xtr = new XMLHttpRequest();
xtr.open('GET', "url", true);
xtr.send();
xtr.onreadystatechange = function() {
if(xtr.readyState === 4 && xtr.status === 200){
console.log(xtr.responseText);
}
}