js 手写代码集合

  • (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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值