前端开发必备技能 —— 数据结构 && 算法 && 手撕JavaScript/ES6
Posted Kabukiyo 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的主要内容,如果未能解决你的问题,请参考以下文章