js数据类型
string常用方法
数组方法
Number的操作方法
时间方法
localStorage的使用
js冒泡排序
js函数基础
闭包
克隆
url的操作
js常用操作方法
一、请注意:JS的数据类型有8种。
在ES5的时候,我们认知的数据类型确实是 6种:Number、String、Boolean、undefined、object、Null。
ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。
二、js数据类型分为基本数据类型和引用数据类型
1.基本数据类型: string Number boolean null undefined
2.引用类型:object 里面包含function Array Date
string常用方法
1.charAT(index) //返回指定索引出的字符串
2.concat(str1,str2) //连接多个字符串
3.indexOf(str) //返回str在字符串中第一次出现的位置,若没有则返回-1
4.lastIndexOf(str) //返回在字符串中最后一次出现的位置,若没有则返回-1
5.slice(start.end) //返回字符串start和end之间的字符串 不包含开始位置,包含结束位置
6.split(“”) //将字符串分割成一个由字符串组成的数组
7.toLowerCase():将字符串转换为小写
8.toUpperCase():将字符串转换为大写
9.search() //方法搜素特定值的字符串,并返回匹配的位置
10.substring()//类似于slice、不能接收负值
11.substr() //类似于slice,第二个参数是返回的长度
12.replace() //用另一个值替换在字符串中指定的值,返回新的字符串,只能替换首个匹配
13.trim() //方法删除字符串两端的空白符
str = str.replace(/\s+/g,“”); 去除空格所有空格
数组方法
1.join(‘规定分隔符’) //可以将所有的数组元素结合为一个字符串
2.toString( ) 把数组转换为数组值(逗号分隔)的字符串
3.pop()// 从数组中删除最后一个元素
4.push() //向数组结尾处,添加一个新的元素
5.shift()//方法会删除首个数组的元素,
6.unshift() //向数组开头添加新的元素
7.splice(‘添加新元素的位置’ ,定义删除多少个元素,‘向数组添加的元素’) //向数组添加新项 位置从1开始
如果仅删除一个元素,则返回一个元素的数组。 如果未删除任何元素,则返回空数组。
8.concat() //合并一个,创建新的数组
9.slice(1,3)//从数组中截出一个新数组,包含开始位置,不包含结束位置,
array.indexOf() 方法判断数组中是否存在某个值,如果存在,则返回数组元素的下标,否则返回-1。
array.includes() 此方法判断数组中是否存在某个值,如果存在返回true,否则返回false
10.filter()数组过滤
找出符合条件的返回新的数组,不改变原数组
var newarr = [
{ num: 1, val: 'ceshi', flag: 'aa' },
{ num: 2, val: 'ceshi2', flag: 'aa2' },
{ num: 2, val: '5555', flag: 'aa2' },
]
/过滤出num==2的
var arr=newarr.filter(item => item.num===2 )
console.log(arr)
//过滤出没有2的字符
var arr = ['10','12','23','44','42']
var newArr = arr.filter(item => item.indexOf('2')<0)
console.log(newArr)
11.sort() //数组排序
直接更改的是原数组
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
//1,5,10,25,40,100
12.reverse() //数组反转
13forEach() //方法为每个数组元素调用一次函数
//1.forEach不会返回执行结果
//使用forEach操作数组对象,数组对象会改变原数组
let arr=[
{name:'孙悟空',age:'500'},
{name:'猪八戒',age:'800'},
]
arr.forEach(item=>{
arr[0].name="沙僧"
})
console.log(arr);
14.map() //方法通过对每个数组元素执行函数来创建新数组。
15.for in 循环 获取的是数组下标从0位置开始
var arr=[1,2,3,4]
function xun(){
for(let key in arr){
console.log(key);
}
}
xun()
//遍历数组对象
var arr=[
{name:'孙悟空',age:500},
{name:'猪八戒',age:30},
]
function xun(){
for(let key in arr){
//获取的是每一项
console.log(arr[key]);
}
}
xun()
14.for of循环 //遍历普通数组获取的是值 遍历数组获取的是每一项
var arr=[1,2,3,4]
function xun(){
for(let key of arr){
console.log(key);
}
}
xun()
//遍历数组对象
var arr=[
{name:'孙悟空',age:500},
{name:'猪八戒',age:30},
]
function xun(){
for(let key of arr){
console.log(key);
//打印结果
{name:'孙悟空',age:500},
{name:'猪八戒',age:30},
}
}
xun()
15.find() 找出符合规则的第一个数据或者是第一组
返回一个新的数组
const arr=[1,2,3,4,5]
var arr1=arr.find((item)=>{
return item>3
})
console.log(arr1);//4
findIndex()//返回符合条件的下标,如果没有返回-1
let a=1;
let arr=[2,5,1,3]
let index=arr.findIndex(v=>v===a);
console.log(index);//2
16.reduce()//为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组
1.基本语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
callback (执行数组中每个值的函数,包含四个参数)
1、total (必需。初始值, 或者计算结束后的返回值(上一次调用回调的返回值)。)
2、currentValue (必需。当前被处理的元素)
3、currentIndex(可选。当前元素的索引)
4、arr (可选。当前元素所属的数组对象。)
initialValue (作为第一次调用 callback 的第一个参数。)
2.reduc简单用法
fun1(){
var arr = [1, 2, 3, 4];
var sum = arr.reduce((x,y)=>x+y)
var mul = arr.reduce((x,y)=>x*y)
console.log( sum ); //求和,10
console.log( mul ); //求乘积,24;
}
2.1求数组最大(最小)值
fun1(){
let arr=[1,58,9,8,6,55]
var max = arr.reduce(function (prev, cur) {
return Math.max(prev,cur);
});
var min= arr.reduce(function (prev, cur) {
return Math.min(prev,cur);
});
console.log(max,min);
}
2.3计算数组中每个元素出现的次数
let name = ['JavaScript','Html','Css','Jquery','JavaScript']
let nameNum = name.reduce((pre,cur)=>{
console.log(333,pre,cur)
//in操作符检查某一个属性是否在对象中。单独使用需要接‘’号
//console.log(111,'a'in{a:'3'})
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre //上一次回调的返回值
},{})
console.log(222,nameNum)
///
333 {} "JavaScript"
333 {JavaScript: 1} "Html"
333 {JavaScript: 1, Html: 1} "Css"
333 {JavaScript: 1, Html: 1, Css: 1} "Jquery"
333 {JavaScript: 1, Html: 1, Css: 1, Jquery: 1} "JavaScript"
222 {JavaScript: 2, Html: 1, Css: 1, Jquery: 1}
17.Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。
let a={a:1,b:2}
let b=Object.assign({},a)
console.log(b);
//{a:1,b:2}
18.some()
找出符合条件的,返回值是true或false,当找到第一个满足条件的就终止循环,不在继续查找
var points = [40, 100, 1, 5, 25, 10];
var sum= points.some((item)=>{
return item>80
})
console.log(sum);//true
Number的操作方法
1.NaN是JavaScript保留字,表示数字不是合法数字。
2.toString() 讲数字转为字符串
3.toFixed() 保留小数点位数
4.Number( 需要转换的变量 ) 将变量转换为数字
5.parseInt( 需要转换的变量 ) 将变量转换为数字
6.parseFloat( 需要转换的变量 ) 将变量转换为数字
7.isNaN(x) //判断非数字, 如果是数字返回false 如果不是数字返回true
8.Math.的方法
let num=2.6;
console.log(Math.ceil(num)); //向上取整 3
console.log(Math.floor(num));//向下取整 2
console.log(Math.round(num));//四舍五入 3
console.log(Math.random()*100);//返回 0 ~ 1 之间的随机数
利用Math.random获取随机整数
console.log(parseInt(Math.random()*10));//获取0~10之间的整数
console.log(Math.floor(Math.random()*(10+1)));//获取0~11之间的整数,
console.log(Math.floor(Math.random() * (8-5) + 5));//获取5~8之间的整数
var k = Math.floor(Math.random() * (8 - 5 + 1) + 5);//获取5~9之间的整数
console.log(k);
时间方法
JS中获取时间
//单独调用new Date(); 显示这种格式 Mar 31 10:10:43 UTC+0800 2012
const date=new Date//获取时间戳,时间对象
const year=date.getFullyear()//获取当前年
const month=date.getMonth()//获取月份0-11,0是一月
const day=date.getDate()//获取今天是几号1-31
const hours=date.getHours()//获取当前小时数
const mm=date.getMinutes()//获取分钟数0-59
const s=date.getSeconds()//获取秒0-59
const w=date.getDay()//获取当前星期几0-6,0是周一
date.getTime() //获取十三位的时间戳1657097850229
`new Date()`可以有参数,如果没有参数获取的是当前的时间对象,参数可以是时间字符串或者是时间戳,则转换对应时间的时间对象.但是要注意格式
new Date('2021/07/14'); //正确 , Wed Jul 14 2021 00:00:00 GMT+0800 (中国标准时间)
new Date('2021,07,14'); //正确 , Wed Jul 14 2021 00:00:00 GMT+0800 (中国标准时间)
new Date(1626244866842); //正确 , Wed Jul 14 2021 14:41:06 GMT+0800 (中国标准时间)
new Date('2021-07-14'); // 错误的,这种格式是不支持的,
new Date("2021-07-14".replace(/-/g, "/")); //Sat Apr 16 2011 00:00:00 GMT+0800 (中国标准时间)
获取当前年月日,时分秒
在memethods中定义方法
currentTime() {
//设置一个定时器一秒执行一次,函数后面不要加小括号
//加小括号的是立即调用
setInterval(this.getDate, 500);
},
getDate: function() {
var _this = this;
let yy = new Date().getFullYear();
let mm = new Date().getMonth() + 1;
let dd = new Date().getDate();//获取今天是几号
let week = new Date().getDay();//获取今天星期几
let hh = new Date().getHours();
let ms =
new Date().getSeconds() < 10
? "0" + new Date().getSeconds()
: new Date().getSeconds();
let mf =
new Date().getMinutes() < 10
? "0" + new Date().getMinutes()
: new Date().getMinutes();
if (week == 1) {
this.nowWeek = "星期一";
} else if (week == 2) {
this.nowWeek = "星期二";
} else if (week == 3) {
this.nowWeek = "星期三";
} else if (week == 4) {
this.nowWeek = "星期四";
} else if (week == 5) {
this.nowWeek = "星期五";
} else if (week == 6) {
this.nowWeek = "星期六";
} else {
this.nowWeek = "星期日";
}
_this.nowTime = hh + ":" + mf + ":" + ms;
_this.nowDate = yy + "/" + mm + "/" + dd;
}
},
在mounted,HTML渲染后调用
mounted() {
this.currentTime();
},
// 销毁定时器
beforeDestroy: function() {
if (this.getDate) {
console.log("销毁定时器");
clearInterval(this.getDate); // 在Vue实例销毁前,清除时间定时器
}
}
获取几天后的时间,如果是获取几天前的时间,那就是减
function GetDateStr(AddDayCount) {
var dd = new Date();
dd.setDate(dd.getDate()+AddDayCount);//获取AddDayCount天后的日期
// dd.setMonth(dd.getMonth()+AddMonthCount) 月后
//dd.setYear(dd.getFullYear()+AddYearCount);//获取AddMonthCount年后的日期
var y = dd.getFullYear();
var m = dd.getMonth()+1;//获取当前月份的日期
var d = dd.getDate();
//判断 月
if(m < 10){
m = "0" + m;
}else{
m = m;
}
//判断 日n
if(d < 10){//如果天数<10
d = "0" + d;
}else{
d = d;
}
return y+"-"+m+"-"+d;
}
第三方组件moment
https://www.cnblogs.com/Jimc/p/10591580.html
设置显示区间~
localStorage的使用
list:{num:5,price:15,}
localStorage往浏览器存是要把对象解析成字符串
localStorage.setItem('todolist',JSON.stringify(this.list)) //存,第一个属性要存的键名,第二个属性是value值
open(){ localStorage.setItem('todolist',JSON.stringify(this.list))
},
从localStorage中获取todolist
localStorage.getItem('todolist')//取
getLocalStorage(){
let todoList=JSON.parse(localStorage.getItem('todolist'))
console.log(todoList);
},
localStorage.removeItem()//删除
deLocalStorage(){
localStorage.removeItem('todolist')
}
Js冒泡排序
var arr=[15,45,6,3,89]
从大到小排序
for(let i=0;i<arr.length-1;i++){//需要排序的次数,
//内层循环表述数组元素与其他元素交换的次数,规律为 j=arr1.length-i-1
for(let j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
//设置中间变量来交换位置
var swap=arr[j];
arr[j]=arr[j+1];
arr[j+1]=swap;
}
}
}
js函数基础
在js函数中,赋值方式创建的函数,和声明方式创建的函数在使用时,是完全一样的,只不过在程序开始执行前,赋值方式可避免函数被声明提前。
1.声明式: 普通函数,一定有函数名称。
function 函数名称() {
函数体
}
一、.函数作用域
1.概念:变量的有效范围
2.全局变量:①.在全局有效的变量,②.定义方式:函数外定义,③.生命周期:从定义开始,到页面被卸载结束
3.局部变量:只在局部有效的变量
定义方式:函数内定义
生命周期:一般情况下从定义开始,到函数执行完毕
4.函数作用域
只有函数才可以产生新的作用域
只有函数可以限定变量的有效范围
闭包
什么是闭包?
能够读取其他函数内部变量的函数,
全面的解答:
在js中变量的作用域属于函数作用域, 在函数执行完后,作用域就会被清理,内存也会随之被回收,但是由于闭包函数是建立在函数内部的子函数, 由于其可访问上级作用域,即使上级函数执行完, 作用域也不会随之销毁, 这时的子函数(也就是闭包),便拥有了访问上级作用域中变量的权限,即使上级函数执行完后作用域内的值也不会被销毁。
另一方面的理解
闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包是怎么形成的?
1.外层函数的作用域对象被内层函数引用着无法释放,
闭包怎么实现?
1.外层函数包裹内层函数
2.外层函数将内层函数返回到外部
3.调用外层函数获取到内层函数的变量
闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
怎么来理解这句话呢?请看下面的代码。
nAdd=function(){n+=1}既然是全局变量为什么可以访问fun(){}中的局部变量n呢?
答:其实这个函数干了2件事情
1.先创建一个函数----在fun内的-----孩子是fun生的
2.然后才把fun生的孩子赋值给了全局变量,才从fun中出来
所以,因为function是fun生的,所以使用自己父母的局部变量是情理之中
function f1(){
var n=999;
//匿名函数声明了没有调用
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
//第一次调用的时候没有执行nAdd()
//调用以后一直在内存中
result(); // 999
nAdd();
result(); // 1000
闭包的缺点
1.比普通函数占用更多内存
2.闭包不会自动释放,容易造成内存泄漏
闭包是指作用域:全局作用域和函数作用域,能够读取其它函数内部变量的函数
闭包解决的问题
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中。不会在函数调用后被清除
关于闭包的另外一个例子,函数调用
function fun(){
var name='any'
function fn(){
console.log(name);
}
//只有调用才有返回值
// 1.return出去,只是把这个函数的给return出去了,并没有调用,因为么有加小括号
return fn
}
// fun()调用的话,就是调用的这个函数,并没有返回值,把fun()函数返回值,赋值给一个新的变量
// 2.把fun函数用变量f接着,f()调用时才执行fn
// 把函数的返回值,赋给f
var f= fun()
//类似于,
// var f=function(){
// console.log(name);
// }
f()
函数练习
不管传几个参数执行相加的结果
function add(){
// b保存每次累加的值
var sum=0
// 遍历arguments
for(let i=0;i<arguments.length;i++){
// 每遍历一个实参值,就累加到sum上
sum+=arguments[i]
}
return sum
}
console.log(add(1,2,1,6))
循环与闭包,期望每隔一秒打印递增数字
function bibao(){
for (var i=1; i<=5; i++) {
//匿名函数自调
(function() {
var j = i;
setTimeout(()=> {
console.log( j );
//换成人话就是一秒执行一次,第一秒执行1,第二秒执行2
//实现一秒输出一个数
}, j*1000 );
})();
}
}
bibao()
面向对象
一、面向对象的三大特征:封装,继承,多态
1.封装
们平时所用的方法和类都是一种封装,当我们在项目开发中,遇到一段功能的代码在好多地方重复使用的时候,我们可以把他单独封装成一个功能的方法,这样在我们需要使用的地方直接调用就可以了。
2.继承
继承在我们的项目开发中主要使用为子类继承父类,下面是es6继承的书写方法
克隆
js的数据类型
基本数据类型:数值型,字符串型,布尔型,null,undefined
引用数据类型:函数,数组,对象
1.克隆对象是基本数据类型我们可以直接赋值给我们需要的变量即可
<script>
var a=10;
var b=a;
console.log(a); //10
console.log(b); //10
b=520;
console.log(a); //10
console.log(b); //520
</script>
可以看到的是对于基本类型来说,我们将一个基本类型的值赋予 a 变量,接着将 a 的值赋予变量 b ;然后我们修改 b ;可以看到 b 被修改了,而 a 的值没有被修改,两个变量都使用的是独立的数据;
2.克隆对象是引用数据类型则不能直接复制
<script>
var a=[1,2,3];
var b=a;
b.push(520); //使用push向b数组末尾添加一个元素,但会发现a,b数组都添加了
console.log(a); //[1,2,3,520]
console.log(b); //[1,2,3,520]
</script>
可以看到的是,两个对象的值全部被修改了
对象是引用类型的值,对于引用类型来说,我们将 obj1 赋予 obj2 的时候,我们其实仅仅只是将 obj1 存储在栈堆中的的引用赋予了 obj2 ,而两个对象此时指向的是在堆内存中的同一个数据,所以当我们修改任意一个值的时候,修改的都是堆内存中的数据,而不是引用,所以只要修改了,同样引用的对象的值也自然而然的发生了改变
一,浅拷贝
对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,因为它们公用一条数据
二、深拷贝
当将拷贝的对象修改某个复杂数据的属性的时候,被拷贝的对象的字段也会进行修改,下面我们来看一个案例
var obj={
stu:{name:'小明',age:26}
}
var obj2={};
Object.assign(obj2,obj)
obj2.stu.name='小红';
console.log(obj);
console.log(obj2);
当我们修改了obj中的stu的name字段,两个对象中的name字段都变成了小红,这就说我们说的浅拷贝
如何实现深拷贝
使用JSON.parse(JSON.stringify(obj))
let obj = JSON.parse(JSON.stringify(this.queryItem));
var obj={
stu:{name:'小明',age:26}
}
var obj2=JSON.parse(JSON.stringify(obj));
obj2.stu.name='小红';
console.log(obj);
console.log(obj2);
1.性能问题,stringify再解析其实需要耗费较多时间,特别是数据量大的时候。
2.一些类型无法拷贝,例如函数(不输出),正则(输出空对象),时间对象(输出时间字符串),Undefiend(不输出)等等问题。
js实现深拷贝
var arr=[12,13,14]
function deepClone(obj){
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === 'object') {
for(let key in obj){
if (obj[key] && typeof obj[key] === 'object'){
objClone[key] = deepClone(obj[key]);
}else{
objClone[key] = obj[key]
}
}
}
return objClone;
}
function shenClone(){
var b=deepClone(arr);
b[1]=888
console.log(b);
}
shenClone()
console.log(arr);
1.原型链
1.什么是继承?
继承是面向对象编程中的一个重要概念,通过继承可以使子类的实例使用在父类中定义的属性和方法
url的操作
1.获取url?后面的参数split 方法将参数提取出来
let URL = "http://www.baidu.com?name=张三&age=25&sex=男&wife=小红"
function getUrlParams(url) {
// 通过 ? 分割获取后面的参数字符串
let urlStr = url.split('?')[1]
// 创建空对象存储参数
let obj = {};
// 再通过 & 将每一个参数单独分割出来
let paramsArr = urlStr.split('&')
for(let i = 0,len = paramsArr.length;i < len;i++){
// 再通过 = 将每一个参数分割为 key:value 的形式
let arr = paramsArr[i].split('=')
obj[arr[0]] = arr[1];
}
return obj
}
console.log(getUrlParams(URL))
获取整个url
window.location.href // http://localhost:8060/list.html?nav=6&index=1&iframe=%2Fenterprise%2Findex
获取问号后面的
window.location.search //?nav=6&index=1&iframe=%2Fenterprise%2Findex
获取url域名
window.location.host // localhost:8060
获取端口号
window.locatiom.port
url编码
escape() / unescape() 一些浏览器已经弃用
规则:
除了ASCII字母、数字、标点符号"@ * _ + - . /"以外,对其他所有字符进行编码(注:空格会被转化为+字符)
注:
escape用来对某个字符串进行编码的,不能直接用于url编码,尽管url也是个字符串。所以如果你需要编码整个URL,那么用decodeURI()是专门着眼于对整个url进行编码的。
ECMAScript v3 反对使用escape()方法,现在已经很少使用,应用使用 decodeURI() 和 decodeURIComponent() 替代它
encodeURI() / decodeURI()
用途:
encodeURI()是Javascript中真正用来对URL编码的函数。
规则:
不会对下列字符编码 ASCII字母 数字 ~ ! @ # $ & * ( ) = : / , ; ? + '(注:这是单引号,若果双引号"会被编码%22)进行编码
结果:输出utf-8形式,并且在每个字节前加上%。
encodeURIComponent() / decodeURIComponent()
用途:
与encodeURI()的区别是,它用于对URL的组成部分(如查询参数、路径等)进行个别编码,而不用于对整个URL进行编码。
规则:
不会对下列字符编码 ASCII字母 数字 ~ ! * ( ) '(注:这是单引号,若果双引号"会被编码%22)进行编码
结果:和encodeURI一样,输出utf-8形式,并且在每个字节前加上%。
3.区别
encodeURIComponent比encodeURI编码的范围更大,即 @ # $ & = : / , ; ? +,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码
如果只是编码字符串,不和URL有半毛钱关系,那么用escape。当然该方法已经不推荐使用,所以不用深究
encodeUR用于编码整个URL
encodeURIComponent用于编码url中的查询参数或路径等(若参数为url,还是相当于参数,用encodeURIComponent())