前言
做题家的api仓库。
重要api参考手册
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects
从我多年的刷题经验来看,刷题圈最重要的东西永远是2个。
1.字符串(扩展number等类型)
字符串操作永远是最基础最繁琐但是学会了又很没用的玩意。
因为在各种OJ中,I/O是最基础的。
所有人学语言都是先学print。
string类的api要会。
怎么做string format。
然后extend to number, date …等其他简单数据类型。
怎么做到string number互转。
怎么做date to string format
2.数组 (扩展set)
array类的api要会。 (在cpp中就是vector,换了个名字而已)
然后扩展到stack,queue,set等其他容器结构。
array实现stack非常简单。
array实现queue只需要一个index求余,也很简单。
array实现set要看具体语言,用c++刷题的话,STL里自备转换函数。
在上面两个之外,还有一个很公用的是dict类
在python里 list + dict +set可以完成几乎所有需要的序列操作。
在JS里这玩意叫Map
Array + Map + Set 也可以实现类似的功能。
而dict可以是set的上位替代,因为dict.keys本身就是一个set。
所以一切序列操作可以简化为list + dict。
零、基本语法
1.循环
遵循类似cpp的语法
for(let i=0;i<length;i++){
}
2. 布尔运算(逻辑、比较)
js中恒等用3个等于号 ===
不等就是 !==
与&&
或 |
3.校验
//类型
var a = 1;
console.log(a instanceof String); //false
console.log(a instanceof Number); //true
//判空校验
很遗憾JS不提供判空函数。
虽然有一个特性是,null, undefined, "", NaN
都作为false。
但你不知道这个东西是不是0或者false,毕竟0、false本身不是空。
但可以通过===
做到细致化判空。
//判空
var a = undefined;
var b = null;
if(a=== undefined){ console.log('a true');} //a true
if(b=== null){ console.log('b true');} //b true
//但恒等号不能判断NaN
var c = NaN;
if(c=== NaN){ console.log('true');} //无输出
if(c!== NaN){ console.log('false');} //false
//得用isNaN()
if( isNaN(c)){ console.log('c is NaN');} //c is NaN
一、数值Number
构造函数上的两个宏观定义量
- Number.MIN_VALUE
- Number.MAX_VALUE
二、字符串String
//支持类似数组的index访问
var s = "abc123";
console.log(s[0]); // 'a'
//等价于s.charAt(0) //返回字符串中的第0个字符
//split
var a = s.split("");// 传入空分隔符时,每个字符一个元素
console.log(a); // ['a','b','c','1','2','3']
//join
var b = a.join("-");
console.log(b); // "a-b-c-1-2-3"
//拼接
//支持直接加法
var s2 = s + "def456";
//截取 slice, 左闭右开[)区间。不修改原字符串。
var s3 = s.slice(1,3);
console.log(s3); // "bc"
var s4 = s.slice(2); // 不输入第二个参数时,默认到字符串末尾'\0'结束。
console.log(s4); // "c123"
//局部删除(反向截取)
var s ="aabbcc";
console.log(s.replace('bb', ''));// 'aacc'
//或者转array后用splice再join. splice的好处是精细化
var arr = s.split('');
arr.splice(2,2);
arr.join('');
字符串查找
String没有 find!
只有String.search() , String.indexOf()
string.indexOf() ,失败返回-1
三、数组Array
我理解的,js中的Array,本质上是一个字典。
虽然你可以传数字进去取值 console.log(arr[0])。
但是你去拿index,拿出来也会发现是string类型的数字。
var arr = Array([1,2,3])
for( const idx in arr){
console.log(typeof idx) //string
}
所以用arr[‘key’]的形式去理解会更好。
这个说法也不是没有根据的。。
毕竟js里万物皆继承于Object,Object的基本格式又是{key:value}。
Array类只是对Object做了一些类似于c++中数组的封装。
使其看起来差不多。
本质上说是字典一点也不为过。
因为它甚至可以跨index存值。
var arr =new Array()
arr[0] = 'a'
arr[9] = 'b'
console.log(arr)
不过这样输出的结果会变成一个length=10的数组,中间元素帮你置空了。
Array API
全世界都知道的
1. IO
- push()
- pop() 有返回值。
- .length属性
头部操作
- Array.shift()
删除第一个元素。inplace。
返回从数组中删除的元素; 如果数组为空则返回undefined 。 类似pop
- Array.unshift(element1, …, elementN)
向数组头部添加若干元素。inplace。
注意,返回值是数组的new length。
删+增
- Array.splice(start[, deleteCount[, item1[, item2[, …]]]])
在指定位置开始删除count个元素后,再依次插入item1,2,…。
return: An array containing the deleted elements.
inplace操作,原地修改。
拷贝
浅拷贝用 Array.slice()
即可。不能直接赋值。
- array.slice(start, end)
返回一个浅拷贝副本。
不提供end,则从start开始截至最后一个元素。
不提供start和end,默认拷贝整个数组。
清空
大部分浏览器没有提供clear()这种api。
直接赋值 array.length = 0
,这样就能完成清空。
或者用array.splice(0, array.length)
。
2. 校验
类型校验
- Array.isArray()
或者用 instanceof Array
判空
没有提供API。
只能用 Array.prototype.length === 0
来判空。
3. 批操作
拼接
- Array.concat()
返回新数组,对input无影响。
这个函数的参数可以是无限多个Array,都会拆开拼接。
用ES6的解构语法也可以实现拼接功能
var a = [1,2,3]
var b = [4,5,6]
a.push(...b)
console.log(a) //[1,2,3,4,5,6]
批量赋值
只能在支持ES6解构的环境使用
var a;
var b;
a,b = [1,2];
console.log(a,b);
反转
- Array.reverse()
截取
- Array.slice()
slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
4.查找
查找一般来说需要支持自定义查找
所以我最常用的是find,这玩意也好记。
返回值是第一个符合条件的元素。
Array.prototype.find( (el, index?, arr?)=>boolean): unknown
const arr = [1,2,3];
const res = arr.find((x)=> x>1)
console.log(res)
//打印 2
Array.find的后两个可选参数比较少用到,分别是当前element的index,和整个数组。
const arr = [1,2,3];
const res = arr.find((x,i,arr)=> {console.log(i,arr); return x>2;})
console.log(res)
//打印
//0 [1,2,3]
//1 [1,2,3]
//2 [1,2,3]
includes()
indexOf()
5.排序
查找之后肯定有排序。
- Array.prototype…sort( 自定义函数 )
Array.sort是原地操作,会改变原数组。
自定义函数 (a,b) => Number , 返回值 [ 负数,0,正数] 。 负数时a排前。为0时不改变ab相对位置(但不是所有浏览器都遵守这点)。
内置循环
Array.forEach()
Array.map()
//https://javascript.info/array
四、Map
var map = new Map();
//插入元素
map.set(k,v);
//获取元素
map.get(k); //返回v
//判断存在
if (map.has(k)) {
return map.get(k);
}
//获得所有值
map.keys(); //返回array
map.values(); //返回array
//遍历
map.entries(); //返回迭代器 (k,v)
for(const item of map.entries()){
const [k,v] = item;
console.log(k,v);
}
用ES5语法实现class。
刷题的时候发现,有些OJ平台好像不支持class关键词。
通过让你写出构造函数的方式,自定义一个类。
所以用ES5语法实现class是必须掌握的。
做到这一点的关键是,所有会在实例中用到的局部变量,都在写constructor的时候用this包裹就好了。
LC刷题列表
由于某种原因,前端的算法题一般不会很难。
又由于某种原因,前端的考察范围里,线性表的比重会很高。
异步打印题
//这里有篇文章写的非常之好!!!强烈安利!!!
//https://juejin.cn/post/7016298598883131423
做了一份前端面试复习计划,保熟~
//https://juejin.cn/post/7061588533214969892
刷题的时候还是会感觉有些不舒服。
想放弃命令式,变得更声明式一点。
需要几个feature。
在python的时候这种内置api是很好用的,但JS没有。
快速产出指定序列的数字,对标python的range(n) , range(1,n)。
JS中可以勉强用 Array(n).forEach((_,i)=>{ })
来产出 i
。
但显然这样只适用于0开始。