前端开发必备技能 —— 数据结构 && 算法 && 手撕JavaScript/ES6

Posted Silam Lin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端开发必备技能 —— 数据结构 && 算法 && 手撕JavaScript/ES6相关的知识,希望对你有一定的参考价值。

前端开发必备技能 —— 手写系列之数据结构

数据结构

二叉树

二叉树中序遍历

二叉树前序遍历

二叉树后序遍历

判断二叉树是否为对称二叉树

三级目录

算法

排序

冒泡排序

  • 第一轮大循环,将本数组最大的数移到最后面
  • 第二轮大循环,将本数组第二大的数移到倒数第二个
  • 不断地交换,不断地把当轮循环中最大的数往后挪
  • 时间复杂度O(n^2),空间复杂度O(1)
function bubbleSort(array)
	for (let i = 0; i < array.length; i++)
		let isComplete = true;
		for (let j = 0; j < array.length-j-1; j++)
			if(array[j]>array[j+1])
				[array[j],array[j+1]] = [array[j+1],array[j]];
				isComplete = false;
			
		 
		if (isComplete) 
			break;
		
	
	return array;

选择排序

  • 进行n-1次大循环
  • 每次大循环,目的在于遍历当前大循环元素后面的所有元素,以查找出最小的元素
  • 不断把最小的元素与当前元素交换
  • 时间复杂度O(n^2),空间复杂度O(1)
function selectionSort(array) 
   for (let i = 0; i < array.length - 1; i++) 
       let minIndex = i;
       for (let j = i + 1; j < array.length; j++) 
          if (array[j] < array[minIndex]) 
              minIndex = j;
          
    	
        [array[i], array[minIndex]] = [array[minIndex], array[i]];
   
 

插入排序

  • 从数组的第二个开始遍历,直至最后一个
  • 大循环遍历目的在于,将当前目标元素插到前面合适的位置
  • 如果比前面的元素小,就不断交换位置
  • 直至它比前面的元素都要大,则这就是它合适的位置。
  • 时间复杂度O(n^2),空间复杂度O(1)
function insertSort(array) 
    for (let i = 1; i < array.length; i++) 
      let target = i;
      for (let j = i - 1; j >= 0; j--) 
         if (array[target] < array[j]) 
           [array[j], array[target]] = [array[target], array[j]]
            target = j;
          else 
            break;
         
      
   
   return array;

快速排序

    function quickSort(array, start, end) 
      if (end - start < 1) 
        return;
      
      const target = array[start];
      let l = start;
      let r = end;
      while (l < r) 
        while (l < r && array[r] >= target) 
          r--;
        
        array[l] = array[r];
        while (l < r && array[l] < target) 
          l++;
        
        array[r] = array[l];
      
      array[l] = target;
      quickSort(array, start, l - 1);
      quickSort(array, l + 1, end);
      return array;
    

手撕javascript/ES6

实现call

  • ① 通过Function.prototype,可以使得所有函数都可以访问myCall
  • ② test.myCall(obj),隐式绑定,使得myCall内部的this指向test函数
  • ③ context[fn] = this;this赋给context的fn属性
  • ④ contextfn;执行。test函数执行,不过此时test的this是指向context的
Function.prototype.myCall = function (context = window, ...args) 
   context = context || window;
   const fn = Symbol();
   context[fn] = this;
   const result = context[fn](...args);
   delete context[fn];
   return result;

关于第三点和第四点的描述,与下面代码的道理是一样的:

var name = 'kabukiyo';
var obj = 
	name : 'testest'

function test()
	console.log(this.name);

test()   // kabukiyo
obj.fn = test();
obj.fn() // testest
  • 把一个函数丢给某个对象的属性
  • 对象的属性执行,相当于执行这个函数,不过此时该函数的this就指向该对象了(this如愿以偿地改变了)

实现apply

apply接收的是数组

Function.prototype.myApply = function (context = window, args) 
	context = context || window;
    const fn = Symbol();
    context[fn] = this;
    let result;
    if (Array.isArray(args)) 
       result = context[fn](...args);
     else 
       result = context[fn]();
    
    delete context[fn];
    return result;

实现bind

Function.prototype.myBind = function (context,...args1) 
    const _this = this
    return function F(...args2) 
      return _this.apply(context, args1.concat(args2))
    


var obj = 
    z: 1
;

function fn(x, y) 
   alert( x + y + this.z);
;

var bound = fn.bind_(obj, 1);
bound(2);
Function.prototype.bind_ = function (obj) 
    //第0位是this,所以得从第一位开始裁剪
    var args = Array.prototype.slice.call(arguments, 1);
    var fn = this;
    return function () 
        //二次调用我们也抓取arguments对象
        var params = Array.prototype.slice.call(arguments);
        //注意concat的顺序
        fn.apply(obj, args.concat(params));
    ;
;

以上是关于前端开发必备技能 —— 数据结构 && 算法 && 手撕JavaScript/ES6的主要内容,如果未能解决你的问题,请参考以下文章

前端开发必备技能 —— 数据结构 && 算法 && 手撕JavaScript/ES6

想学Web前端,你需要了解这些职责和必备技能

接口测试-测试人员必备技能

接口测试-测试人员必备技能

前端必备 HTTP 技能之 Ajax 技术详解

前端开发必备的 5 个「高薪」技能