JavaScript是世界上最优秀的语言之一
任何可以使用js来实现的应用 最终都会使用js实现
变量访问,函数调用、形式可以是?.的形式,称为条件式调用
javascript采用unicode字符转义 \u+4位置16进制字符,es5中加入了{}
void 丢弃这个值并返回undefind
repeat()重复次数
function声明的变量,变量提升具有最高级连等赋值的时候成员访问优先级更高
~ 数字 给数字取反 并-1
&& 运算符 如果左边为真 才回去执行右边的表达式
dir() 打印原型上的方法
数组
数组的增删修查
let arr = []; // 定义一个数组
arr.push(1, 2, 3); // [1,2,3],尾部添加 返回数组长度3 ,可一次添加多个也可单个添加,改变原数组
arr.unshift(4, 5, 6) // [4, 5, 6, 1, 2, 3],头部添加 返回数组长度6,可一次添加多个也可单个添加
//,改变原数组
arr.pop() // [4, 5, 6, 1, 2] 返回数组被删除的那一项3,尾部单个删除,一次只能删除一个,改变原数组
arr.shift() //[5, 6, 1, 2] 返回数组被删除的那一项4,头部单个删除,改变原数组
arr.forEach((item, index, OriginalArray) => { // forEach()接收一个函数作为参数,函数中可接收三个形参
// console.log(item); // item 数组的每一项
// console.log(index); // index 下标
// console.log(OriginalArray); // OriginalArray 原数组
})
arr.reverse() //[2, 1, 6, 5] 将数组进行颠倒 改变原数组
arr.sort((a, b) => b - a) //[6, 5, 2, 1] 数组排序 接收一个函数,函数接收 两个参数a,b,retun a-b(从小到大) 或者 b-a(从大到小) 改变原数组
let str = ['b', 'c', 'a']
str.sort() //["a", "b", "c"] 字母排序 直接调用 改变原数组
let newArr = arr.map((item, index, OriginalArray) => item *10) //[60, 50, 20, 10] 重构数组
//,并返回一个新的数组 item 数组的每一项 index 下标 OriginalArray 原数组
arr.splice(1, 2, 23,34) // [6, 23, 34, 1] 返回删除的元素[5,2],splice数组截取 可接受n个参数,第一个参数是开始截取的下标(包含自己),第二个参数是截取的个数如果不传就是截除剩余所有,从第三个参数开始到往后都是要插入的数据
arr.splice(-3, 2) //[6, 1],第一位数也可以为负数-3就是从倒数第三个开始截取第二位数的个数 修改原数组
arr.slice(0, 1) // [6] 从第0位截取到第一位,包左不包右,返回一个新的数组,不会修改原数组
arr.slice(-2, -1) // [6] 也支持负数 slice数组切片
let filter = arr.filter(x => x > 5) // [6] 数组过滤,不会改变原数组,符合条件回返回一个新的数组
/// filter() 还可以清理数组中稀松空闲 array.filter(()=>true)
let findIndex=arr.findIndex(item=>item==6)// 查找符合要去的元素并返回下标,找不到返回-1
let find=arr.find(item=>item==6) // 查找符合要求的元素,并返回这个值,找不到返回undefined
arr.fill(10,0,2) // 替换数组 10是要替换的数据,0是从哪开始,2到哪里结束
arr.concat([0,2]) // 合并数组 会自动打平一次数组
some() 与 every() 都是循环数组判断的方法,返回值true或false
some()是只要有一个符合条件就返回true
every() 只有全部符合条件才会返回true
在空数组中调用他们some()返回的是false,every()返回的是true
let arr = [0,1,2,3] // 同样的条件一个为true,一个位false
arr.some(item=>item>2) // true
arr.every(item=>item>2) // false
copyWithin 将数组的一部分浅复制到同一数组
<!-- 是基于原数组进行操作,返回的结果也是原数组--!>
// copyWithin 方法有三个参数 第一参数是要插入的位置的下标的后一位,第二个参数是要复制原数组的起始位置
// 第三个参数是要复制原始数组的结束位置,支持负数,负数就是从数组倒着数从1开始
let arr=['a','b','c','d','e','f','g']
// console.log(arr.copyWithin(4)) // ["a", "b", "c", "d", "a", "b", "c"] 这里的4相当于 4,0,4
// console.log(arr.copyWithin(0,3)) // 这里的0,3相当于 3,0,3
// console.log(arr.copyWithin(4,0,4))
reduce()与reduceRight()
reduce()与reduceRight() 都是循环数组的每个元素,执行由reduce()提供的函数,
并将其结果汇总为一个值,
他俩的区别的是:reduce()是从数组的左边开始的reduceRight()是从数组的右边开始的
// reduce()函数由两个值,callback()函数,initialValue是可选的是,循环开始时的默认值,如果循环的
//是一个空数组,不写就会报错
//callback函数中又四个参数 accumulator,上一次处理后的数据,currentValue即将要处理的数据,
//index第一次开始的下标,initialValue值如果写了,就为0,否则为1,也可以忽略不写,array要处理的数组,
//如果是array.reduce(),那么就不用写,
let array = [0, 1, 2, 3]
//第一种写法
reduce(callback((accumulator,currentValue,index,array)=>{
retunrn accumulator+currentValue // 一个数组的中所有相的累加和就计算好了
}),initialValue)
// 第二种写法
arr.reduce((start, end) => { // 结果为6
return start + end
})
数组扁平化 flat() 、flatMap()
(1)递归实现
let arr = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
function myFlat(arr) {
if (!(arr instanceof Array)) return arr
let newArr = []
for (let i in arr) {
newArr = newArr.concat(myFlat(arr[i]))
}
return newArr
}
console.log(myFlat(arr));
(2)flat let arr1=arr.flat(Infinity) 结果与第一种方法一样
(3)flatMap() 是与flat层次为1时一样,性能还更好一点
Array.from() 将伪数组,转化为真正的数组, Array.of()创建并返回一个新数组
浅拷贝和深拷贝的区别
let deepobj = {
a: 1,
b: [{name: '王五'}, {name: '李四'}],
c: function () {},
d: undefined,
e: null,
f: { name: '小明',list: [{name: '1111',age: 12},{name: '张三',age: 24}]}
}
// 手写深拷贝
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) return obj
let result = obj instanceof Array ? [] : {}
for (let key in obj) {
if(!obj.hasOwnProperty(key)) continue
result[key] = deepClone(obj[key])
}
return result
}
let deep = deepClone(deepobj)
deep.f.list[0].name='小黑'
console.log(deepobj);
console.log(deep);
// 浅拷贝后的值如果进行修改了,原始数据也会被修改,深拷贝之后就不会出现这种情况
// 深拷贝层层拷贝,浅拷贝只拷贝一层
// object.assign()
随机四位数
let arr = '1234567890qwertyuiopasdfghjklzxcvbnm';
let arr1 = [];// 存放下标
let arr2 = [];
for (let i = 0; i < arr.length; i++) {
let num = Math.floor(Math.random() * arr.length);
if (arr1.length < 4) {
arr1.push(num);
for (let j = 0; j < arr1.length - 1; j++) {
if (arr1[j] == num) {
arr1.splice(j, 1);
}
}
}
}
for (let k = 0; k < arr1.length; k++) {
for (let i = 0; i < arr.length; i++) {
arr2[k] = arr[arr1[k]];
}
}
随机颜色
//min 与 max 之间的随机数
function ran(min, max) {
return parseInt(Math.random() * (max - min + 1) + min)
}
function cor() {
return '#' + getRand(0, 0xffffff).toString(16)
}
console.log(cor());
</script>
npm install -g cnpm --registry=https://registry.npm.taobao.org
数组length方法,给数组设置长度能决定数组的长度,如果小于原数组长度,只保留前几位,如果不足,用 emty 代替
解决加减乘除浮点问题
计算机是采用二进制编码,常用的数字类型是十进制,当计算机运算时,会把我们的数字转化为二进制,转化的时候会将数字,转化为整数部分和小数部分,整数部分会 / 2 直到结果为 1 或 0,而小数部分会 * 2 直到结果为 1 或 0,问题就出现在这里,除了5其他 * 2 都得不到1 或 0,计算机就会一直计算下去,直到超过一定位数,计算机会直接四舍五入,这也导致我们转化之后的数据,在转化回去,与之前的数据不相同。但是最终结果出现的浮点数字,距离我们的正确的数字,之前有很多个0,可以取用一下方法解决问题,js最大安全数是16位。
// 以加法为例
let num1 = 0.31
let num2 = 0.1
let result = f1 + f2
// result 这时得到的数据,除了末尾的哪一位数其他都是正确的
// 这里采用 toString()转化为字符串,split()分割字符串 toFixed() 保留几位小数
// Number.parseFloat() 转化为数字保留小数部分, Math.max()取最大值
Number.parseFloat(result.toFixed(Math.max(num1.toString().split('.')[1].length),num2.toString().split('.')[1].length));
// 乘法的话,去除math.max()改成 * 就可以了
Number.parseFloat(result.toFixed((num1.toString().split('.')[1].length)*num2.toString().split('.')[1].length));
for ··· in循环出来的是数组下标,for ··· of 循环出来的是数组每一项
// for of 循环对象是会报错的,如果非要循环对象可以使用结构赋值加上 Object.entries()
let obj={x:1,y:2}
for (const [iterator] of Object.entries(obj)) { // [iterator] 结构赋值 Object.entries(obj)将对象的每一次都转化为了数组
console.log(iterator); // iterator 就是x、y
}
while 与 do while 循环
while('条件表达式只要一直为真,就是无限循环'){
// break 结束本次循环 或者 修改判断条件
}
//
do {
// 代码循环体 先执行一次,早进行判断
} while ('条件表达式')
concat 与 … 有着异曲同工之妙 都是将对象展开
对象
in 检测 某一项在不在这个数据中 包括原型上的
hasOwnProperty() 与in差不多 , 不包括原型上的
propertyIsEnumerabe() 检测可枚举属性
getOwnPropertyNames() 与 Object.keys()相似
Object.assign() //浅拷贝数据,也可以理解成数组中的concat方法,用法一样
Object.create() //创建一个指定原型对象的空对象
Object.is(value1,value2) // 判断两个值是否相等 返回Boolean
Object.entries() //将对象的每一项都转化为数组
Object.fromEntries() // 可以将Object.entries()转换之后格式在转换回去
Object.keys() // 将obj中的所有key值添加到一个新的数组里
Object.values() // 将obj中的所有value值添加到一个新的数组里
Object.preventExtensions()//方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
对获取的城市数据首字母随机处理
let city = {},
let cits = {},
let cisz = {},
axios.get("数据地址").then((res) => {//获取数据
city = res.data; //获取初始数据
cits = Object.keys(this.city); // 获取数据中的key值
cits.sort(); // 对key进行排序
cits.forEach((item) => {
cisz[item] = city[item];//最终数据处理完成
});
});
class类
class Rangr{
constructor(){
this.num='123213'
}
get(){
console.log('你是个麻古');
}
}
// new Rangr().get()
class Vister extends Rangr{ // extends 继承
constructor(){
super() // super()使用继承的属性
}
get(){ // 修改继承的方法
console.log(this.num);
// 如果还想使用父类的方法可以这样左
// super.get() // 使用父类的方法
}
}
new Vister().get() // 启动并调用方法
//class 类只能使用 new 实例 调用
常用数据判断方法
typeof 1 // 'number'
[] instanceof Array // true
[].constructor // Array的构造函数
Object.prototype.toString.call([]) // [object Array]
函数
call、apply、bind 改变this指向
call、apply、bind他们共同的特点都是接收的第一个参数就是修改后的this指向
传参call()与bind()是一样的,用,号隔开,只有apply()传的一个参数集合
bind方法是返回了一个新的方法
function f() {
console.log(this);
}
f.apply({x:1}, [1, 2])
f.call({x:1},1,2)
f.bind({x:1})(1)
function fn() {
let args=Array.from(arguments) //Array.from() 将伪数组转化为真正的数组
console.log(arguments.callee); // arguments.callee 获取自己本身的函数
console.log(fn.caller); // 返回谁调用了自身的这个函数
}
报错
throw new Error('') //手动抛错
// try catch 防止代码报错,让程序正常运行
try {
// 写代码位置
}catch (err){
console.log(err) // 捕获错误
}finally {
console.log('无论是否报错都会执行')
}
js错误信息
ReferenceError: a is not defined 引用变量a不存在
TypeError: Cannot set property ‘xx’ of undefined 数据类型错误
console.warn(’警告’);//控制台输出警告框
confirm(‘你是个麻瓜吗?’)//弹出浏览器确认框 返回一个布尔值
console.error(‘你是个麻瓜’) 控制台输出错误信息
try ··· catch 捕获错误信息 可以让页面正常执行,catch 向控制台抛出错误
throw reeor 向控制台抛出错误 throw new Error(‘错误’)
浏览器
// ** 浏览器全屏事件**
//进入全屏
let element = document.documentElement;
element.requestFullscreen()
//退出全屏
document.exitFullscreen();
document.titile='页面标题' // 设置当前页面的title字段
window.navigator.onLine // 属性,这个属性值为true表示设备能上网
定时器
setInterval(()=>{},500) // 会一直执行的定时器
clearInterval() // 清除一直出执行的定时器
setTimeout(()=>{},500) // 一次性定时器
clearTimeout() // 清除一次性定时器
防抖与节流
防抖就是,用户随意触发事件,我清除上一个延迟执行,开启新的延迟执行
let btn = document.getElementsByTagName('button')[0]
let ctime = ''
btn.onclick = function () {
clearTimeout(ctime)
ctime = setTimeout(() => {
console.log('执行了');
}, 500)
}
节流就是用户触发,我还延迟执行,延迟之后,用户在触发事件时是无效的,必须等待我这个事件执行了,
这个事件的函数才能重新触发
//定时器写法
let btn = document.getElementsByTagName('button')[0]
let ctime = ''
let fag = true;
btn.onclick = function () {
if (!fag) return
fag = false
ctime = setTimeout(() => {
clearTimeout(ctime)
console.log('执行了');
fag = true
}, 500)
}
//时间戳写法
let prev=0;
btn.onclicl=funcrion(){
let now=new Date().getTime()
if(now - 500*1000 > prev){
console.log('执行了');
prev = mow;
}
}
set
使用set()工厂函数生成一个不能包含重复值的集合
如果使用add添加object类型的是可以重复的,但是delete会失效因为他只能删除单个值
可以使用for of 和 forEach 循环
let arr = new Set([0]);
arr.add(1) // add('') 添加
arr.size; // size 类似lenght长度
arr.delete(1) // delete() 删除
arr.has(0)) // true has()检测值是否存在
arr.clear();// clear()清空集合
map
let map=new Map()
map.set('x',1).set('y',2) // set(key:value) 添加
map.get('x') // 1 获取键名为x的value值
map.size // 大小
map.has('x') // 检测是否存在
map.delete('x') // delete() 删除
map.clear();// clear()清空集合
for (const [key,value] of map) console.log(key,value);
WebSocket
let websocket = new WebSocket('url');
websocket.onopen
websocket.onerror
websocket.onmessage // 监听数据
websocket.onclose
websocket.send() // 发送消息
FileReader
//数据转换base64
var reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = () => {
this.imgUrl = reader.result;
};
FormData
formData格式数据
const formData = new FormData();
formData.append('file',document.getElementById('input').[0].raw, document.getElementById('input')[0].name);//添加
formData.get('file');//获取
千分符
function thousand(num, sym = ',', colon = 3) {
let toNum = String(num);
let i = 0;
let size = colon;
let arr = [];
for (let j = toNum.length - 1; j >= 0; j--) {
if (size) {
if (!arr[i]) {
arr[i] = [];
}
arr[i].push(toNum[j]);
size--;
if (!size) {
size = colon;
i++;
}
}
}
let res = '';
for (let k = 0; k < arr.length; k++) {
let str = arr[k].join("");
res += `${sym}${str}`;
}
let newStr = res.split('').reverse();
newStr.splice(newStr.length - 1, 1);
return newStr.join("");
}