开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情
前言
高不成低不就,谁又能一直好呢?
BEGIIN
arr.sort()
sort:用于对数组的元素进行排序,并返回数组。默认排序顺序是将元素转换成字符串,然后比较UTF-16代码单元值序列时构建的
arr.sort((a,b)=>{})
- a:第一个用于比较的元素
- b: 第二个用于比较的元素
- 返回值:排序后的数组,数组已原地排序,并不进行复制
- 如果 返回值 > 0,则元素交换位置
- 如果 返回值 < 0,则元素位置不变
- 如果 返回值 = 0,则认为两个元素相等,不交换位置
既然谈到了排序就要讲讲js的十大排序
冒泡排序(Bubble Sort)
原理:两层循环,均从0开始
- 比较相邻的元素,若第一个比第二个大,交换这两个
- 交换到最后,最后一个会是最大的数
- 重复循环
复杂度
- 时间复杂度:最好:
O(n),最坏:O(n^2),so平均复杂度:O(n^2) - 空间复杂度:
O(1)
function bubbleSort(arr){
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
}
console.log(bubbleSort([6,1,2,4,3,5]))
选择排序
原理:设置一个变量 = 找出最小数;两层循环;交换顺序
- 第一层循环,设置变量min = 第一个数
- 进入第二层循环,从第二个数开始,比较第二个数与min的值大小,
- 如果第二个数小于min,把第二个数赋值给min,保证min最小
复杂度
- 时间复杂度:平均复杂度:
O(n^2) - 空间复杂度:
O(1) - 稳定性:不
function selectSort(arr){
var min,temp;
for(var i=0;i<arr.length-1;i++){
min=i;
for(var j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min = j;
}
}
temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
return arr;
}
console.log(selectSort([6,1,2,4,3,5]))
快速排序
原理:分成两部分,小的放左边,大的放右边,拼接
- 如果长度小于2,直接返回
- 设置变量:左边,右边,中间值(最中间的值)
- for循环比较,小的放左边,大的放右边
- 返回拼接:左边+中间值+右边
复杂度
- 时间复杂度:平均复杂度:
O(nlogn) - 空间复杂度:
O(logn) - 稳定性:不
function quickSort(arr){
if(arr.length<2){return arr}
var left=[],right=[],mid=arr.splice(Math.floor(arr.length/2),1);
for(var i=0;i<arr.length;i++){
if(arr[i]<mid){
left.push(arr[i]);
}else {
right.push(arr[i])
}
}
return quickSort(left).concat(mid,quickSort(right))
}
console.log(quickSort([6,1,2,4,3,5]))
插入排序
又分为:直接插入排序、折半插入排序、希尔排序
直接插入
原理:多加一个变量存放待排序的元素,将每一个待排序的元素与已排序的元素进行逐一比较
复杂度
- 时间复杂度:平均复杂度:
O(n^2) - 空间复杂度:
O(1) - 稳定性:yes
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;
}
console.log(insertionSort([6,1,2,4,3,5]))
希尔排序
function shellSort(arr) {
var len = arr.length,
temp,
gap = 1;
while(gap < len/3) { //动态定义间隔序列
gap =gap*3+1;
}
for (gap; gap > 0; gap = Math.floor(gap/3)) {
for (var i = gap; i < len; i++) {
temp = arr[i];
for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
arr[j+gap] = arr[j];
}
arr[j+gap] = temp;
}
}
return arr;
}
js原型链
定义:所有的原型构成一个链条,这个链条我们叫做原型链
原型:proto,prototype,constructor
- proto: js给每个对象添加一个属性,这个属性指向另一个对象的prototype,js可以通过
Object.getPrototypeOf(obj)获取,chrom浏览器实现为__proto__ - prototype:js为每个函数添加一个
prototype属性,表示自己的原型对象。prototype是个对象 - construtor: 是js创建和初始化对象的方法,如果没有自己指定的
construtor,则会默认有个空的construtor。 - 原型对象的
constructor指向自己的创造者,每个原型对象都有constructor。所有对象都会从它的原型上继承constructor属性。
js里有句话:万物皆对象,每个对象都有原型
function Person(name) { // 构造函数
this.name = name;
}
Person.prototype.say = function () { // 原型
console.info('name is' + this.name);
};
const p = new Person('夏利');
console.log(p.name);
p.say();
每个函数都有一个prototype属性,函数的prototype属性指向了一个对象。就是上面的p的原型
补充一下
不要把 _proto_ 和 prototype 弄混淆了。
prototype是一个只存在function中的属性。//重要_proto_是一个只存在对象中的属性。- 在 EcmaScript 规范 中,
_proto_属性被称为[[Prototype]]
- 在 EcmaScript 规范 中,
Web Worker
H5新出的标准,为了利用多核CPU的计算能力。允许js脚本创建多个线程,但是子线程受主线程控制,且不得操作DOM。由此看来,此标准并没有改变js单线程的本质。
在worker线程中,虽然无法直接操作dom节点,也不能使用window对象的默认方法和属性,但仍可以使用window对象下的东西,比如:websocket,indexedDB等
worker和主线程间的数据传递,双方都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中)
数据结构
数组
arr = [1,2,3,4,45,5,6,7,8]
优点
- 遍历方便
- 按照索引查询元素方便
缺点
- 无法扩容
- 数组只能存储一种类型的数据
- 添加,删除耗费时间性能,因为要移动其他的元素
链表
是一种递归的数据结构
栈
先进后出
队列
先进先出
树
非线性结构,由n(n>0)个有限节点组成的一个具有层次关系的组合
target和currentTarget的概念
-
target和currentTarget都是事件对象中的属性-
target是指获取事件的目标。 -
currentTarget是指其事件处理程序当前正在处理事件的那个元素
-
this和currentTarget的关系:
在事件处理程序内部,对象this始终等于currentTarget的值。
let const var
什么是变量提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
三者区别
①var存在变量提升,let const不存在变量提升
②let const 都是块级局部变量(只在当前代码块起作用)
③const与let基本一致,但是const声明时必须赋值,只能进行一次赋值(声明后不可修改),如果是复合类型数据,可以修改其属性
④同一作用域下let const不能声明同名变量,var可以
事件委托
事件代理的原理是
DOM元素的事件冒泡。
事件的冒泡和捕获:分为三个阶段捕获、目标阶段、捕获
-
捕获:从上向目标阶段
-
冒泡:从目标阶段到上
事件委托的优点:
-
可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件
-
可以实现动态绑定
怎么阻止
-
阻止冒泡:e.stopPropagation() || window.event.cancelBubble=true(IE) -
阻止默认事件:e.preventDefault() || return false (return false 仅在dom0级事件处理方法和HTML事件属性中,才能通过return false形式阻止事件宿主的默认行为)
END
一天结束的又快又慢,每天都在重复这些东西,也不知道啥时候能排上用场。加油