内存
栈内存:存储值类型,变量。
堆内存:复杂类型的数据,对象等。其中放栈内存中的变量存储的是在堆内存中的地址,从而指向堆内存。
div元素水平垂直居中的方法
第一种:
<style>
.a {
height: 300px;
background-color: hotpink;
position: relative;
}
.b {
width: 100px;
height: 100px;
background-color: lawngreen;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
</style>
<body>
<div class="a">
<div class="b"></div>
</div>
</body>
第二种:
<style>
.a {
height: 300px;
background-color: hotpink;
position: relative;
}
.b {
width: 100px;
height: 100px;
background-color: lawngreen;
position: absolute;
margin: auto;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
cookie和session 、sessionstorage和localstorage
cookie:Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。
cookie数据存放在客户的浏览器上。cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗。Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。
session:session,服务器为了保存用户状态而创建的一个特殊的对象。当浏览器第一次访问服务器时,服务器创建一个session对象(该对象有一个唯一的id,一般称之为sessionId),服务器会将sessionId以cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据sessionId就可以找到对应的session对象。
session数据放在服务器上。session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。
sessionstorage和localstorage的区别:
localStorage生命周期是永久,除非用户清除localStorage信息,否则这些信息将永远存在;
sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过它存储的数据也就被清空了。
localStorage和sessionStorage一样都是用来存储客户端临时信息的对象。
详细请见转载:cookie、sessionStorage和localStorage的区别_浮生离梦的博客-CSDN博客(写的很好!!!)
http缓存:常见的http缓存只能缓存get请求响应的资源
消除数组中的重复元素
var b = [1, 2, 1, 2, 3, 5, "q", "q", [1],[1, 2],[1]];
var resualt = new Set(b);//将数组中重复元素删除,并以对象形式返回
resualt = Array.from(resualt);//将对象转换为数组
console.log(resualt);
结果:
将数组进行全排列,生成一个新数组
例:["a,b,c"]
全排序为["a,b,c","a,c,b","b,a,c","b,c,a","c,a,b","c,b,a"]
function Allsort1(arr) {
var arr1 = arr[0].split(",");
function swap(arr, i, j) {
if (i != j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
var Arr = [];
//此方法最主要是交换的思路
function perm(arr) {
(function fn(n) { //为第n个位置选择元素
for (var i = n; i < arr.length; i++) {
swap(arr, i, n);
if (n + 1 < arr.length - 1) //根据下标a(b+1) 不是最后一项,判断数组中剩余的待全排列的元素是否大于1个
fn(n + 1); //从第n+1个下标进行全排列
else {
Arr.push(arr.toString());
}
swap(arr, i, n);
}
})(0);
}
perm(arr1);
return Arr;
}
React的四种hook
useState():状态钩子。
纯函数没有状态,useState() 用于为函数组件引入状态。
useContext():共享状态钩子。
作用就是可以做状态的分发,在React16.X以后支持,避免了react逐层通过Props传递数据。
useReducer():Action钩子。
在使用React的过程中,如遇到状态管理,一般会用到Redux,而React本身是不提供状态管理的。而useReducer()提供了状态管理。首先,关于redux我们都知道,其原理是通过用户在页面中发起action,从而通过reducer方法来改变state,从而实现页面和状态的通信。而Reducer的形式是(state, action) => newstate。它接受reducer函数和状态的初始值作为参数,返回一个数组,其中第一项为当前的状态值,第二项为发送action的dispatch函数。
useEffect():副作用钩子。
可以用来更好的处理副作用,如异步请求等,Hooks 的 useEffect()也是为函数组件提供了处理副作用的钩子。
全局状态管理
vue 里通过 vuex实现全局状态管理,在react里可以通过redux或者mobx也可以实现全局状态管理。
js的数据类型
JavaScript的基本数据类型:
值类型 (基本类型) :字符串(String)、数字 (Number)、布尔 (Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型 :对象 (Object)、数组 (Array)、函数 (Function)。.
几种内部基本排序
插入排序
直接插入排序:
折半插入排序:
希尔排序:
交换排序
冒泡排序:
快速排序:
选择排序
简单选择排序:
堆排序:
归并排序:
基数排序:
浏览器的内核
浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎。
主流浏览器
IE/Edge(Trident),Chrome(Webkit,blink ),Safari(Webkit),Opera(Presto,Webkit,blink ),Firefox(Mosaic)。
IE/Edge:微软的IE浏览器浏览器更新至IE10后,伴随着WIN10系统的上市,迁移到了全新的浏览器Edge。除了JS引擎沿用之前IE9就开始使用的查克拉(Chakra),渲染引擎使用了新的内核EdgeHTML(本质上不是对Trident的完全推翻重建,而是在Trident基础上删除了过时的旧技术支持的代码,扩展和优化了对新的技术的支持,所以被看做是全新的内核)
Safari:Safari自2003年面世,就一直是苹果公司的产品自带的浏览器,它使用的是苹果研发和开源的Webkit引擎。Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍生而来。Webkit2发布于2010年,它实现了元件的抽象画,提高了元件的重复利用效率,提供了更加干净的网页渲染和更高效的渲染效率。另外,Webkit也是苹果Mac OS X系统引擎框架版本的名称,主要用于Safari、Dashboard、Mail。
Chrome:提到Chrome浏览器,一般人会认为使用的Webkit内核,这种说法不完全准确。Chrome发布于2008年,使用的渲染内核是Chromium,它是fork自Webkit,但把Webkit梳理得更有条理可读性更高,效率提升明显。2013年,由于Webkit2和Chromium在沙箱设计上的冲突,谷歌联手Opera自研和发布了Blink引擎,逐步脱离了Webkit的影响。所以,可以这么认为:Chromium扩展自Webkit止于Webkit2,其后Chrome切换到了Blink引擎。另外,Chrome的JS引擎使用的V8引擎,应该算是最著名和优秀的开源JS引擎,大名鼎鼎的Node.js就是选用V8作为底层架构。
Firefox:火狐的内核Gecko也是开源引擎,任何程序员都能为其提供扩展和建议。火狐的JS引擎历经SpiderMonkey、TraceMonkey到现在的JaegerMonkey。其中JaegerMonkey部分技术借鉴了V8、JSCore和Webkit,算是集思广益。
Opera:Opera在2013年V12.16之前使用的是Opera Software公司开发的Presto引擎,之后连同谷歌研发和选择Blink作为Opera浏览器的排版内核。
题目1:
牛牛有一个只由字符'1'到'9'组成的长度为 n 的字符串 s ,现在牛牛可以截取其中一段长度为 k 的子串并且将该子串当作十进制的正整数,如对于子串"123",其对应的十进制数字就是123 。
牛牛想让这个正整数尽可能的大,请你帮助牛牛计算该正整数。
函数传入一个长度为 n 的字符串 s 和一个正整数 k ,请你返回答案。
输入例子1:
"321",2
输出例子1:
32
function maxValue(s, k) {
// write code here
var max = s[0];
var x = 0;
var Arr = [];
var resualt = 0;
for (var i = 0; i < s.length - 1; i++) {
max = Math.max(max, s[i + 1]);
}
for (var i = 0; i < s.length; i++) {
if (s[i] == max) {
x = i;
Arr.push(s.slice(x, x + k));
}
}
max = Arr[0];
for (var i = 0; i < Arr.length - 1; i++) {
max = Math.max(max, Arr[i + 1]);
}
resualt = parseInt(max);
return resualt;
}
module.exports = {
maxValue : maxValue
};
补充知识点:*数组的各种用法(js)
创建数组
var array-name = [item1, item2, ...];
var cars = ["Saab", "Volvo", "BMW"];
注:不要最后一个元素之后写逗号
使用 JavaScript 关键词 new
var cars = new Array("Saab", "Volvo", "BMW");
访问数组元素
通过引用索引号(下标号)来引用某个数组元素。
var name = cars[0];
数组索引从 0 开始。
数组是对象
数组是一种特殊类型的对象。在 JavaScript 中对数组使用 typeof 运算符会返回 "object"。
可以使用Array.isArray()判断是否为数组。
可以在数组保存对象。可以在数组中保存函数。甚至可以在数组中保存数组:
myArray[0] = Date.now;
myArray[1] = myFunction;
myArray[2] = myCars;
数组属性和方法
length 属性
返回数组的长度(数组元素的数目)。
遍历数组
for循环、Array.foreach() 函数:
var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];
text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";
function myFunction(value) {
text += "<li>" + value + "</li>";
}
添加或删除数组元素
pop() 方法从数组中删除最后一个元素,返回“被弹出”的值:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.pop(); // 从 fruits 删除最后一个元素("Mango"),x 的值是 "Mango"
push() 方法(在数组结尾处)向数组添加一个新的元素,返回新数组的长度:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.push("Kiwi"); // 向 fruits 添加一个新元素,x 的值是 5
shift() 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引,返回被“位移出”的字符串。
unshift() 方法(在开头)向数组添加新元素,并“反向位移”旧元素,返回新数组的长度。
也可以使用 length 属性向数组添加新元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "Lemon";
既然 JavaScript 数组属于对象,其中的元素就也可以使用 JavaScript delete 运算符来删除:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
delete fruits[0]; // 把 fruits 中的首个元素改为 undefined
但是使用 delete 会在数组留下未定义的空洞,所以推荐使用pop()或shift()。
把数组转换为字符串
toString() 把数组转换为数组值(逗号分隔)的字符串。
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString();
结果:
Banana,Orange,Apple,Mango
join() 方法也可将所有数组元素结合为一个字符串,还可以规定分隔符。
var fruits = ["Banana", "Orange","Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.join(" * ");
结果:
Banana * Orange * Apple * Mango
拼接数组
splice() 方法可用于向数组添加新项,返回一个包含已删除项的数组:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 0, "Lemon", "Kiwi");
第一个参数(2)定义了应添加新元素的位置(拼接)。
第二个参数(0)定义应删除多少元素。
其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。
能够使用 splice() 在数组中不留“空洞”的情况下移除元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1); // 删除 fruits 中的第一个元素
合并(连接)数组
concat() 方法通过合并(连接)现有数组来创建一个新数组,不会更改现有数组,返回一个新数组:
var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys); // 连接 myGirls 和 myBoys
可以使用任意数量的数组参数:(三个数组)
var arr1 = ["Cecilie", "Lone"];
var arr2 = ["Emil", "Tobias", "Linus"];
var arr3 = ["Robin", "Morgan"];
var myChildren = arr1.concat(arr2, arr3); // 将arr1、arr2 与 arr3 连接在一起
也可以将值作为参数:
var arr1 = ["Cecilie", "Lone"];
var myChildren = arr1.concat(["Emil", "Tobias", "Linus"]);
裁剪数组
slice() 方法用数组的某个片段切出新数组,创建一个新数组,不会从原数组中删除任何元素。
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1);
可接受两个参数,比如 (1, 3)。
该方法会从开始参数选取元素,直到结束参数(不包括)为止。
如果结束参数被省略,比如第一个例子,则 slice() 会切出数组的剩余部分。
自动 toString()
如果需要原始值,则 JavaScript 会自动把数组转换为字符串。下面两个例子将产生相同的结果:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString();
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits;
数组排序
sort() 方法以字母顺序对数组进行排序:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // 对 fruits 中的元素进行排序
反转数组
reverse() 方法反转数组中的元素,可以使用它以降序对数组进行排序:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // 对 fruits 中的元素进行排序
fruits.reverse(); // 反转元素顺序
数字排序
当 sort() 函数比较两个值时,会将值发送到比较函数:function(a, b){return a-b},并根据所返回的值(负、零或正值)对这些值进行排序。
通过一个比值函数让sort() 函数按照数字顺序对值进行排序:
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
使用相同的技巧对数组进行降序排序:
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a});
以随机顺序排序数组
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return 0.5 - Math.random()});
查找最高(或最低)的数组值
在对数组进行排序之后,您能够使用索引来获得最高或最低值。
也可以使用 Math.max.apply 来查找数组中的最高值:
function myArrayMax(arr) {
return Math.max.apply(null, arr);
}
Math.max.apply([1, 2, 3]) 等于 Math.max(1, 2, 3)。
可以使用 Math.min.apply 来查找数组中的最低值:
function myArrayMin(arr) {
return Math.min.apply(null, arr);
}
Math.min.apply([1, 2, 3]) 等于 Math.min(1, 2, 3)。
排序对象数组
JavaScript 数组经常会包含对象:
var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];
即使对象拥有不同数据类型的属性,sort() 方法仍可用于对数组进行排序。
解决方法是通过比较函数来对比属性值:
cars.sort(function(a, b){return a.year - b.year});
数组迭代
Array.forEach()
forEach() 方法为每个数组元素调用一次函数(回调函数)。
var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);
function myFunction(value, index, array) {
txt = txt + value + "<br>";
}
三个参数:
- 项目值
- 项目索引
- 数组本身
Array.map()
map() 方法通过对每个数组元素执行函数来创建新数组,不会对没有值的数组元素执行函数,不会更改原始数组。
这个例子将每个数组值乘以2:
var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);
function myFunction(value, index, array) {
return value * 2;
}
Array.filter()
filter() 方法创建一个包含通过测试的数组元素的新数组。
这个例子用值大于 18 的元素创建一个新数组:
var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
Array.reduce()
reduce() 方法在每个数组元素上运行函数,以生成(减少它)单个值,在数组中从左到右工作,不会减少原始数组。
这个例子确定数组中所有数字的总和:
var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction);
function myFunction(total, value, index, array) {
return total + value;
}
此函数接受 4 个参数:
- 总数(初始值/先前返回的值)
- 项目值
- 项目索引
- 数组本身
reduce() 方法能够接受一个初始值:
var sum = numbers1.reduce(myFunction, 100);
Array.reduceRight()
reduceRight() 方法在每个数组元素上运行函数,以生成(减少它)单个值,在数组中从右到左工作,不会减少原始数组。
这个例子确定数组中所有数字的总和:
var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduceRight(myFunction);
function myFunction(total, value, index, array) {
return total + value;
}
Array.every()
every() 方法检查所有数组值是否通过测试。
这个例子检查所有数组值是否大于 18,返回true或false:
var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
Array.some()
some() 方法检查某些数组值是否通过了测试。
这个例子检查某些数组值是否大于 18,只要有一个满足就是true:
var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
Array.indexOf()
indexOf() 方法在数组中搜索元素值并返回其位置。
注释:第一个项目的位置是 0,第二个项目的位置是 1,以此类推。
检索数组中的项目 "Apple":
var fruits = ["Apple", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple");
语法:array.indexOf(item, start)。
item | 必需。要检索的项目。 |
start | 可选。从哪里开始搜索。负值将从结尾开始的给定位置开始,并搜索到结尾。 |
如果未找到项目,Array.indexOf() 返回 -1。
如果项目多次出现,则返回第一次出现的位置。
Array.lastIndexOf()
Array.lastIndexOf() 与 Array.indexOf() 类似,但是从数组结尾开始搜索。
检索数组中的项目 "Apple":
var fruits = ["Apple", "Orange", "Apple", "Mango"];
var a = fruits.lastIndexOf("Apple");
Array.find()
find() 方法返回通过测试函数的第一个数组元素的值。
这个例子查找(返回)大于 18 的第一个元素的值:
var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
Array.findIndex()
findIndex() 方法返回通过测试函数的第一个数组元素的索引。
这个例子查找大于 18 的第一个元素的索引:
var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
数组 Const
用 const 声明的数组不能重新赋值,const 变量在声明时必须赋值:
const cars = ["Saab", "Volvo", "BMW"];
cars = ["Toyota", "Volvo", "Audi"]; // ERROR
关键字 const 有一定误导性。
它不定义常量数组。它定义的是对数组的常量引用。
因此,我们仍然可以更改常量数组的元素。
// 您可以创建常量数组:
const cars = ["Saab", "Volvo", "BMW"];
// 您可以更改元素:
cars[0] = "Toyota";
// 您可以添加元素:
cars.push("Audi");
用 const 声明的数组具有块作用域。
在块中声明的数组与在块外声明的数组不同。