JS
Day01
什么是js的组成?
- ECMAScript(es) 其实就是js的规范(规则)
- DOM 文档对象模型 div span
- BOM 浏览器对象模型
JS的使用方式
-
行内样式的书写(不经常使用)
<div onclick="alert("您好!")"></div>
-
内嵌式
<script> alert("你好!") </script>
-
外链式
<script src="./js/xx.js"></script>
变量
-
变量的意义?
存储某一个东西,方便后续的使用
-
变量的定义:创建一个变量(后续可以使用)
-
变量的赋值:往 创建的变量内 存储某一个值(未赋值的内部有一个默认的值 undefined )
-
定义的语法
//var 变量名 //var:关键字 代表后续使用的变量 var a; //创建一个变量 名为a var a1 //创建一个变量 名为a1 a=100; //变量的赋值 /* a=100; a:变量名 =赋值号 100 值(放到盒字里面的东西) */ var a=200; /* var a=200; var 代表关键字:代表后续创建变量 b 变量名 =赋值号 将它右侧的值,存储到左侧的变量中(不是等号) 200 值 (自定义)可以是任何数值 */
-
console.log
-
在浏览器控制台中,打印一些 我们想要的值
-
语法:console.log (我们想要打印的数据)
console.log(100) console.log("梦想从这里起飞!")//打印文本时,需要使用引号包裹(单引号双引号都可以) //打印单词时,需要使用 单引号 || 双引号 都可以
-
-
如何使用变量??
- 声明变量 var a=100
- 将变量a的值打印到控制面板 console.log(a)
-
命名规范(最好最守,否则报错)
规范:= 左右空格
命名要见名知意
尽力不用拼音
行尾号 推荐加 但是需要根据公司的要求
规则一定遵守。否则 报错
-
变量的命名规范
-
字母、数字、$ 符号(数字、不能开头)
var a=1; var a1=1; //var 1a=11 数字开头,导致报错 var a$=1; var a_=11; //-、* 不可以 有其他作用
-
不能使用关键字或者保留字
-
关键字:var if function
-
保留字:现在还没有特殊功能,但将来可能会有 如:let
var var=1; //var作为关键字,不能用做变量名
-
-
驼峰命名法:
- 横杠连接(中划线) .big-box(class类名可以,变量名不行)
- 下划线 big_box (class 类名 ,变量都可以)
- 驼峰命名法,bigBox (两个单词拼接时,第二个首字母大写)
-
预解析:
- var a;
- var b;
- log
- a=123
结果 undefined
-
值的类型
-
值的类型
-
基础数据类型(简单数据类型)
-
数字类型(number类型)
整数,浮点数
-
字符串类型(需要使用引号包裹)string类型
-
undefined类型(未定义)
-
布尔类型:true/false
-
null类型(空)
-
-
复杂数据类型(引用数据类型)
- object类型
-
-
检测值类型的方法
语法:
-
typeof(要检测的数据)
-
typeof 要检测的数据
console.log(typeof 100) //number console.log(typeof '100')//string console.log(typeof undefined)//undefined console.log(typeof true)//boolean console.log(typeof null) //object /*null的类型就是null 之所以typeof 会检测出object 类型,是typeof的问题,与null的类型无关。 解决方法:使用Object.prototype.toString.call(null) */ console.log(Object.prototype.toString.call(null))//任何数据都能精确的打印 [object null]
-
-
值类型的转换
-
Number(数据)方法
-
转型函数Number()可以用于任何数据类型,将其他数据类型转为数字
-
字符串:纯数字字符串转为对应数字,空字符串和空白字符串转为0,非空非纯数字字符串转为NaN
-
布尔值:true转为1,false转为0
-
undefined:转为NaN
-
null:转为0
var a='100' Number(a) console.log(typeof Number(a)) var b=""//空字符串 var c=" "//空白字符串 console.log(Number(b)) //0 console.log( Number(c))//0 //根据js的转换规则 console.log(typeof Number(undefined)) //NaN 非数字的数字 console.log(typeof Number(null))//0 console.log(typeof Number(false))//0 console.log(typeof Number(true))//1
-
-
parseInt()方法:字符串转整数方法
-
对浮点数进行取整操作
- 对数字取整直接舍弃小数部分,只保留整数
-
将字符串转为整数数字
- 将字符串转为整数数字,也包含取整功能
-
字符串中,必须是纯数字字符串或者数字字符开头的字符串,才能转换为正常数字,且只取整数部分
-
如果不是数字打头的字符串,会转换为NaN
//parseInt 用来将其他类型的数值 转换为整数 console.log(parseInt(1.1)) //1.1 console.log(parseInt(1.9)) //1 console.log(parseInt(1.3456789)) //1.1.
-
-
parseFloat()方法:字符串转浮点数方法
-
将字符串转为浮点数数字
-
满足浮点数数字字符必须在字符串开始,如果不在开始返回值都是NaN
-
parseFloat console.log(1.1) // 1.1 console.log(parseFloat(1.1)) // 1.1 console.log(parseFloat('1.1')) // 1.1 console.log(parseFloat('1.1abc')) // 1.1 console.log(parseFloat('abc')) // NaN console.log(parseFloat(undefined)) // NaN console.log(parseFloat(null)) // NaN console.log(parseFloat(true)) // NaN console.log(parseFloat(false)) // NaN
-
-
-
转换字符串
-
变量.toString()`方法
-
String(变量)
方法,有些值没有toString()
,这个时候可以使用String()
。比如undefi【ned
和null
-
+ 号拼接字符串方式
- num + “” ,当 + 两边一个操作符是字符串类型,一个操作符是其他类型的时候,会先把其他类型转换成字符串在进行字符串拼接,返回字符串
var a=100; console.log(typeof(a+'')) console.log(100 + 300)//400 console.log(100 + '300') //100300 /* +号,在js在代表将左右两侧的值,如100+300 等于400 但是,如果在+号两侧 出现一个字符传类型,那不在运算两者相加而是运算,两者的拼接,且得到的值,对字符类型的值 */ //toString 方法, //number 类型 可以调用 //boolean 类型,可以调用 //undefined 不能使用 toString 方法 //null 不能使用 toString 方法 //如果想要将undefined 或者null 转换为string类型 //1、可以通过+ ''的方式 //2、String(变量) var a; console.log(typeof a.toString())//报错
-
-
转布尔类型
-
Boolean(变量)方法
- 转型函数Boolean()可以用于任何数据类型,将其他数据类型转为布尔类型的值
- 转为false:NaN、0、“”空字符串、null、undefined
- 转为true:非0 非NaN数字、非空字符串
-
//数字转换为布尔值,非0即为真
console.log(Boolean(100))//true
console.log(Boolean(0))//false
console.log(Boolean(-100))//false
----------------------------
//转为false:NaN、0、"" 空字符串、null、undefined
//转为true:非0 非NaN数字、非空字符串
console.log(Boolean(''))//false
console.log(Boolean(' '))//true
console.log(Boolean('cmx'))// true
作业:去掘金搜索一些其他的值类型的检测方法
tyepof [value]
:检测数据类型的运算符
[example] instanceof [class]
: 检测某一个实例是否属于这个类
[example].constructor===[class]
:检测实例和类关系的,从而检测数据类型
Object.prototype.toString.call([value])
:检测数据类型
详情:https://juejin.cn/post/6844904115097567239#heading-1
Day02
运算符
- 隐式转换:JS内部帮助我们转换的
- 显示转换:我们自己手动通过方法转换数据类型
- 除了加法数据类型不是number类型时会进行拼接,其他的都不会拼接,会隐式转换
console.log(1+2) //3
console.log(1+'2') //12(String)
console.log(2-2) //0
console.log(2-'2') //0
---------------------------------------
console.log(2 *2) //4
console.log(2*'2') //4
---------------------------------------
console.log(2/2) //1
console.log(2/'2') //1
---------------------------------------
console.log(7%2) //1
console.log(7%'2')//1
JS的赋值
-
可以用赋值号赋值
-
+=、-=、*=\、/= 、%=
var a=1; //a=a+1 ==>a+=1 //我自身 赋值为 我自身+1 ----------------------------- a=a-1 ==>a-=1 ----------------------------- a=a*2 ===>a*=2 ----------------------------- a=a/2 ===>a/=2 ----------------------------- a=a%2 ===>a%=2
-
做什么的?
运算
-
可以不用??
可以
-
用了有什么好处???
简化代码量
-
-
// >、<、 >=、 <= 、==、 =、 !=、 !
// >、<、 >=、 <= 、==、 ===、 !=、 !==
console.log(1>2)//false
console.log(1<2)//true
-------------------------------
/*
== 等于
= 赋值
=== 全等于
==和===作用一样,用于对比两侧数据是否相等
==只对比数据,不对比数据类型
=== 对比数据,其对比数据类型
== 在对比数据类型时。两侧数据不同,比如,一侧数字,一侧字符串。会进行隐式转换
*/
console.log(2==2) //true
console,log(2==='2') //false
-------------------------------
/*
!= 不等于
!== 不全等于
两者作用不相同,用与对两侧数据是否相同。相同时返回false,不相同返回true
!= 只对比数据。不对比数据类型(会进行隐式转换。转换为相同类型)
!== 对比数据,且对比数据类型
*/
console.log(2!=2) //false
console,log(2!='2') //false
console,log(2!=='2') //true
-
逻辑运算符: &&的优先级高于 ||
-
&&(逻辑与 逻辑且)
/* 逻辑与 语法:1、变量1 && 变量2 2、 表达式1 && 表达式2 返回方式: 前真后假:false 前假,直接返回false 全真为真,返回true */ var a=true && false //前一个为真。返回后一个 var b=false && true //第一个为假。直接返回前一个。所以会把false 返回 /* var a=0 && 1 逻辑与 左侧为0 右侧为1 0转换为布尔值,会转换为false(非0即为真) 按照逻辑与的返回方式,前一个为假(左侧为假),那么会返回第一个(左侧的值) var a=1 && 0 逻辑与 左侧为1 右侧为0 1转换为布尔值,会转换为true(非0即为真) 按照逻辑与的返回方式,前一个为真(左侧为真),那么会返回后一个(右侧的值) */
-
||(逻辑或)
/* 逻辑或 */ var a=1 ||0 //1 /* 逻辑或 左侧为1 右侧为0 1转换为布尔值为真,转换为true (非0即为真) 按照逻辑或的返回方式 第一个为真(左侧为真),返回左侧 第一个为假(左侧为假),会返回右侧的(后一个,第二个) */ var a= 0||1 //1 /* 逻辑或 左侧为0 右侧为1 0转换为布尔值为真,转换为false(非0即为真) 按照逻辑或的返回方式 第一个为真(左侧为真),返回左侧 第一个为假(左侧为假),会返回右侧的(后一个,第二个) */
-
!(逻辑非,取反、非)
var a=true; console.log(a) //true console.log(!a) //false /* 作用: 改变变量值的布尔值 */ var b=0 console.log(b) //0 console.log(!b) //true 0-->false 取反-->true var c=1 console.log(typeof c)//number console.log(typeof !c)//false console.log(typeof !!c)//true
-
自增自减(++/–)
/* 变量名 前 或者 后 写在++(--) var a=0; a++; ++a; */ var a=0; var b=++a;//1 //++在前 ,先运算,然后参与周围表达式 /* var b=++a 1、先给a自增1,a的值为1 2、参与周围表达式的运算,把a的值赋值给变量b var c=a++ 1、把a的值直接赋值给c(此时还未自增,也就是说a的值为0) 2、a 自增1 */ var a=0 var b=--a /* --在前,先参与自减,然后参与周围表达式 var b=--a 1、a先参与自减,此时值为-1 2、把a自减的值,赋值给吧(此时b为-1) 在后,先参与周围表达式,然后参与自减 var b=a-- 1、a参与周围表达式的运算,也就是说把a赋值c(此时a为0 ,所以b的值也是0) 2、然后a自减(此时b为-1) */
-
分支语句
-
什么是分支语句?
基于某一个条件。决定执行哪一段代码
-
if分支语句
-
需求:基于某一个条件,只打印123 或者 456
-
语法:if(条件){当条件为真时,执行的代码}
var a=1; if(a===1){ console.log(1) console.log(2) console.log(3) } if(a===2){ console.log(4) console.log(5) console.log(6) }
-
if(){}…else{}
- if关键字
- ()条件
- {} 要执行的代码
- else{} 当前边所有的条件都为假的时,他会执行
if(a==1){ console.log(1) console.log(2) console.log(3) } else{ console.log(4) console.log(5) console.log(6) }
-
if…else if …else
-
新需要:
/*a==1,打印1 a==2,打印2 a==3,打印3 如果a不满上述条件打印 ,打印100*/ if(a==1){ console.log(1) } else if(a==2){ console.log(2) } else if(a==3){ console.log(3) } else{ console.log(100) }
-
总结:if判断从上到下一次检查,查询是否满足条件
如果满足,则仅执行当前分支,其他不执行
如果不满足,则会进行下一个if的判断,成功则执行, 不成功则继续往下执行,直到最后一个if成功则执行, 不成功则不执行
最后,查看是否有else 分支。如果有,且前边所有的if 条件都为假
-
-
switch…case
switch(条件){ case 1: 满足case 1 时,执行的代码 break; case 2: 满足case 2 时,执行的代码 break; ..... default: console.log("xxxxx") }
var a=1; switch(a){ case 1: console.log('a为1') break; case 2: console.log('a为2') break; default: console.log("上述代码都没有执行") }
-
switch case 在做对比的时候,使用的是严格的全等,也就是说会对比,数据类型
-
default 会在上述条件(case)都不满足时,执行的
-
swtich…case的 穿透现象
- 当case后没有跟随break时,会从第一个满足条件的case开始执行,一直到最后一个
- 或者说 到后续 的最近一个break
var num=5 switch(num){ case 1: console.log("现在时1月") case 2: console.log("现在时2月") case 3: console.log("现在时3月") case 4: console.log("现在时4月") break; case 5: console.log("现在时5月") }
-
-
三元表达式
-
什么式三元表达式?
也式JS分支语句的一种
-
语法:条件 ? 条件为真时执行:条件为假时执行
true ? console.log("条件为真"):console.log('条件为假')
-
三元表达式:他执行的代码段只有一行。
-
-
//1、
var a = 3; //a==3
a++; //a==3
a++; //a==4
var b = a+2; //b==7 a==5
++a; //a==6
console.log(a) //a=6
//2、
console.log(3 - "36" % 5 + "2" - 2);
//3-1+"2"-2
//2+"2"-2
//"22"-2
//20
//3、
var a = 4; //a==4
var num = 1 * (2 + 3) && a++ || 5 > 6 && 7 < 8 || !9;
console.log(num);
//5 && 4 || false && true || false
// 4 || false || false
// 4 || false
// 4
//4、
var a = 3; // a == 3
var b = a++; // b == 3 a == 4
a + b + a++
// a + b + a++
// 4 + 3 + 4
// 11
//5、
console.log(parseInt(1 * 100 / 3 + ""))
/**
* parseInt(1 * 100 / 3 + "")
* parseInt(100 / 3 + "")
* parseInt(33.333333333... + "")
* parseInt('33.333333333...')
* 33
*/
Day03
循环语句
什么是循环语句??
帮助我们多次执行某一个代码段
- 需要:在浏览器控制台打印50次1(循环语句)
while循环
-
基于某一个条件。循环处理 某一段代码
-
语法:
while(条件){ //要循环执行的代码 }
-
死循环
var num=1; while(num<5){ //死循环 console.log(1) }
-
循环
var num=1; while(num<5){ console.log(1) num++ //自增1 直到5跳出循环 }
-
循环的组成
- 初始化条件
- 条件判断,不符合是结束循环
- 循环执行的代码
- 改变自身。如果不写,死循环
do…while()循环
-
语法:
do{ //要执行的代码 } while(条件)
-
和while循环的差异
while循环首次执行就会判断条件,条件不符合就不会执行 do...while循环,首次就执行,不需要判断条件,执行完毕在去
-
循环代码
var num=10 do{ console.log(1) num++ } while(num<6) /* 首次执行 1、直接执行{...}代码,所以会打印1,num++ 2、判断条件 num<6 ,此时num一定大于6 ,所以条件为 false,条件false直接停止循环 */
for循环
-
语法
for(1、声明变量;2、判断条件;3、改变自身){}
-
小案例:
-
输出10次1
//1、输出10次1 for(var i=0;i<10;i++){ console.log(1) }
-
在1000到2000的数字内,需要求出是4的倍数。且不是100的倍数的那个数字
新需求:不打印到控制台,输出在页面
新新需求:持续输出在页面, 但是每4个换行
var num=0 //计数器,计算达到每4个换行 for(var i=1000;i<2000;i++){ if(i%4==0 && i%100 !=0){ console.log(i) document.write(i+'') num++ if(num == 4){ document.write("<br>") num=0 } } }
-
水仙花
- 有一个二位数,个位 十位 百位 三个位置的3次方 的和等于它自身
for(var i=100;i<1000;i++){ //现在拿到了三位数,我们现在应该拿到了三位数,各个位置上的数字 var bai=parseInt(i / 100) var shi=parseInt(i % 100 / 10) var ge=i % 10 // var sum=bai*bai*baid +shi*shi*shi + ge*ge*ge; var sum=bai**3 + shi ** 3 + ge ** 3 //** 表示返回 肉测的变量或值的X次方。这个X就是**右侧数字 if(i==sum){ console.log(i + '这个数字是水仙花数') } }
-
质数
- 当一个数字 只能被1和它本身整除,那么它是一个质数
- prompt() :JS当中可以让用户输入一些文本传递给JS
- 注意:prompt返回的用户输入值是string类型;如果用户点击了取消。则返回 null
-
-
(console.log(num,typeof num);)
//var num=+prompt("请输入一个数字"); var num=prompt("请输入一个数字")-0; var count=0; for(var i=2; i<num;i++){ if(num % i == 0){ count =count +2 } } count==0?console.log("是质数"):console.log("不是质数") ------------------------------------- var num=prompt("请输入一个数字")-0; for(var i=2; i<num;i++){ if(num % i == 0){ break; } }
流程控制语句
- break;关键字的应用
- continue 关键字 的应用
- 共同点:都可以打断循环
- 不同点:
- break:当我们想满足某一个条件时,停止整个循环,可以使用break;
- continue:当我们想满足某一个条件时,停止当前本轮循环,后续的循环正常执行
循环嵌套
-
什么是循环嵌套。
循环嵌套,两个循环叠在一起
-
语法
for(var i=0;i<3;i++){ console.log('第'+i+'次循环'); for(var j=0;j<3;j++){ console.log(j) } }
-
外层循环执行一次,内层循环 就会完整的 执行一次
-
案例 一
*** *** ***
代码:
for(var i=0;i<3;i++){ //行数 for(var j=0; j<3 ;j++){ //列数 document.write('*') } document.write("<br>") }
-
注意:循环嵌套的条件或变量,不能与内层循环的相同
-
案例 二
* ** *** ****
代码:
for(var i=1;i<=4;i++){ for(var j=1;j<=i;j++){ document.write('*') } document.write('<br>') } /* 第一次执行 i==1 该执行的内层循环 j==1 因为j<=i 此时 i的值为1 所以内层循环 此时会执行1次 也就是只会打印一次* 内层循环的结束后,执行document.write('<br>'),外层循环第一次执行 第二次执行 i==2 该执行的内层循环 j==1 因为j<=i 此时 i的值为2 所以内层循环 此时会执行2次 也就是只会打印两次* 内层循环的结束后,执行document.write('<br>'),外层循环第二次执行 第三次执行 i==3 该执行的内层循环 j==1 因为j<=i 此时 i的值为3 所以内层循环 此时会执行3次 也就是只会打印三次* 内层循环的结束后,执行document.write('<br>'),外层循环第三次执行 第四次执行 i==4 该执行的内层循环 j==1 因为j<=i 此时 i的值为4 所以内层循环 此时会执行4次 也就是只会打印四次* 内层循环的结束后,执行document.write('<br>'),外层循环第四次执行 第五次执行 i==5 因为外层循环的条件为i<=4 所以本轮不执行没停止循环 */
-
案例三:九九乘法表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ padding: 0; margin: 0; } tr{ height: 50px; } td{ width: 150px; text-indent: 20px; background-color: #333; color: white; font-size: 20px; font-weight: bold; font-family: '宋体'; border: 1px solid #fff; border-top: 0; } </style> </head>   <body> <script> for(var i=1;i<=9;i++){ document.write(`<table cellspacing=0><tr>`) for(var j=1;j<=i;j++){ document.write(`<td> ${ j} × ${ i} = ${ i*j} </td>`) } document.write(`</tr></table>`) } </script> </body> </html>
-
案例四:
苹果 3元,梨 2元 , 桃子1元,问:用200元 买100个水果有多少种方案???
for(int a=9;i<=100;i++){ for(int b=9;b<=100;b++){ for(int c=0;c<=100;c++){ if(a*3+b*2+c*1 =200 && a+b+c==1){ System.out.println(a+"个苹果,"+ b + "个梨" + c + “个桃子” ) } } } } //js同理 int===>var /let //输出改为 document.write("")
Day04
函数
什么是函数??
首先排除,不是数学中的函数;函数可以理解为一个点;
为什么要有函数,函数的功能是什么??
帮我们把项目多个地方用到的功能(代码段),抽离出来(就把他拿到那个小盒子,就不需要在多个地方写重复的功能);
然后在需要的地方 调用函数即可
写一个完整的函数
写一个函数(或者说一个完整的函数)
分为两部分
1、定义阶段
2、调用阶段
函数的定义
-
语法:
function(){}
-
两种定义函数的方式:
- 赋值式定义
var fn=function(){} ----匿名函数
function: 关键字,表明后续紧跟一段代码,是函数
() 内部书写,参数 ,后续讲,暂时记住,暂时理解 为 固定写发
{} 内部书写,函数调用执行时 的代码,要执行的代码
-
声明式定义
function 函数名(){}---->具名函数 function: 关键字,表明后续紧跟一段代码,是函数 fn(函数名):将来可以通过 这名字(变量) 去调用(会找到)本函数 {} 内部书写,函数调用执行时 的代码,要执行的代码
-
不管是函数定义式如何定义的,调用方式只有一种
-
语法:函数名()
赋值函数:
由于赋值函数没有函数名,数据存储在变量中,所以可以把变量理解为函数名,即调用方法 函数名()
-
-
函数声明式和赋值式的区别
-
书写不同
var fn=function(){ } function fn1(){ }
-
打印时,声明式会带上函数名;赋值式没有
-
调用时有差异
fn1() //111 function fn1(){ console.log('111') } fn1() //111
声明式可以在函数定义前 调用
fn() //报错 var fn=function()(){ console.log('111') } fn() //111 -------------------------- //预解析 //浏览器做变量提升 var f; //备注:这一行会在当前最开始的那一行,第一行 fn() //fn is not a function //原因在于,此时fn 经过变量提升,有fn,但值为 undefined
赋值式不可以在函数定义前 调用
函数是做什么的??
-
我们的函数在不参与的时候,可以正常执行
-
但!功能相对单一
-
如果函数想要真正的灵活起来,在多个地方调用时,有不同的执行,那么我们可以通过函数的参数来完成
-
参数分为两个
-
形参:函数名后(function)后面的小括号,没书写的一个,相当于在函数内部声明一个变量,可以在函数内部去调用
-
实参:调用函数时的小括号内部书写的值,就是实参
function fn(a,b){ //形参 console.log(a,b) } //实参 fn(1,2) //打印1 2 fn(2,3) //打印2 3 -------------------- function add(a,b){ console.log(a+b) } add(1,2) //3 add(2,3) //5
-
形参与实参会一一对应
- 如果实参数量少于形参,那么前边的形参对应受值,没有对应的实参的形参值,为undefined
- 如果形参的属性 少于 实参 。那么会一一对应后,多余的实参,无法通过 函数获取
//1 function fn(a,b,c){ console.log(a,b,c) } fn(1) //1 undefined undefined fn(2,3)//2 3 undefined //2 function fn(a){ console.log(a) } fn(1) //1 fn(2,3)//2
-
函数的返回值
-
函数的返回值:
-
语法
return 需要返回的内容
-
案例
function add(a,b){ return a+b; } var sum=add(1,2) console.log(sum) //3
-
函数默认返回值
我们可以不写return 函数会默认在代码段最后一行,写上return undefined
function fn(){ console.log(1) } var sum=fn() //调用fn函数(打印1就是在此时执者),将fn函数内部返回值,存储给sum,因为我们没有写return,所以默认值 console.log(sum)//undefined
-
需求:运算两个数,并打印在控制台
function fn(a,b){ console.log(a+b) } fn(1,2)
-
新需求:运算两个数的值,并将其返回,以便后续使用
function fn(a,b){ return a+b } var sum=fn(1,2) console.log(sum) //3
-
return 中断函数
function fn(){ console.log(1) return console.log(1) console.log(1) console.log(1) }
-
我们要写返回值吗?我们什么时候需要??
返回值的书写,取决于是否需要得到函数内部某一个变量的值,如果需要 可以使用返回值将其返回,如果不需要我们可以不写
-
return
- 具有中断函数的共功能
- 如果不想中断函数,那么一定将return放到函数的最后
- 除非就是想要通过return中断函数的运行
-
案例一 水仙花
function fn(num){ //1、书写代码 //1.1 拿到 个位,十位,百位 var bai=parseInt(num/100) var bai=parseInt(num%100/10) var ge=num%10 //1.2 拿到各个位置的三次的值 var sum=bai **3 + bai ** 3 +ge ** 3 //2、如果是水仙花数,返回true 如果不是水仙花数 返回false if(sum==nume){ //水仙花数 return true } else{ //非水仙花数 return false } } var bo=fn(153) console.log(bo) var bo1=fn(666) console.log(bo1)
-
案例二
- 需要参数吗? 两个
- 需要返回值吗?? 不需要
function fn(a,b){ var num=0 for(i=a;i<=b;i++){ if(i % 4 == 0 && i % 100 !=0){ document.write(i +' '); num++ if(num == 4){ document.write('<br>') num=0 } } } } fn(1000,2000)
-
案例三
/* 需要参数吗? 需要两个 一个控制行 一个控制列 需要返回值?? 不需要 */ function fn(num1,num2){ for(var i=0;i<num1;i++){ for(var j=0;j<num2;j++){ document.write("*") } document.write("<br>") } } fn(5,6)
-
案例四
计算两个数的和,并且在此之前。如果哟有一个参数不是 number 那么停止函数
需要参数吗? 需要 两个
需要返回值吗 ?? 需要**
function add(a,b){ if(typeof a !=="number" || typeof b!== "number"){ console.log("参数a或者b参数,其中有一个不是number类型的,终止函数运行") //停止函数 return flase; } console.log('a+b的和:',a+b) return a+b } add(100,200)
-
案例五
/* 需不需要参数?? 需要 需不需返回值 ?? 需要,并最好是布尔值 是--》true 否--》false */ function fn(a){ //1、判断传入的参数是否为质数 var count=0; for(var i=2;i<a;i++){ if(a%i==0){ count=count+40 } } //2、根据出入的参数决定返回值是什么 if(count ===0){ //应该返回true return true } else{ //应该返回false return flase } //不能使用三元表达式,判断 } var a=fn(9) console.log(a) //false var b=fn(7) console.log(b) //true
-
函数的预解析
-
书写代码
fn() function fn(){ console.log(1) } fn() //预解析之后(会把函数提升到当前作用块最顶层)(暂时理解为 当前代码的第一行) /* 1. fn() 不需要 2. function fn(){} 需要预解析 3. fn() 不需要 ---------------------------- 1.function fn(){} //提升到了当前代码最开始的第一行 ... 2. fn() //正常调用 3. fn() //正常调用 */
-
函数的预解析,可能会遇上同名变量提升(变量的预解析) 直接以函数为主
-
JS编程时应该尽量避免变量名和函数名同名,否则会发生相互覆盖的问题.从实际测试效果来看,这种覆盖可以分为两种情况:
- 定义变量时只使用var定义变量,不分配变量初始值,此时函数的优先级更高,函数会覆盖变量;
- 定以变量时为变量指定了初始值,此时变量的优先级更高,变量会覆盖函数.
-
预解析的分析
var fn='hhh' //有提升 console.log(fn) //没有 fn()//没有 function fn(){ //有 console.log(1) } fn() //没有 ---------------------------------------------------------------- //预解析之后 function fn(){ //第一行 console.log(1) } var fn //第二行 没意义 fn='hhh' //这行很重要,直接将变量保存的函数,更改为了 'hhh' console.log(fn) //按照分析,此处应该打印 'hhh' fn() //按照分析,此处fn 的应该为'hhh' 所以会报错 fn is not a function fn() //按照分析 此处fn 的值还是'hhh',所以还会报错 fn is not a function
预解析详解:http://t.zoukankan.com/ggll611928-p-13156966.html
day05
作用域
-
作用是有使用区间的,变量不是说明之后在哪里都可以用,他有一个使用的范围,我们把这个范围叫做 作用域
-
作用域的分类:
-
全局作用域:
-
JS给我们提供了一个叫做window的全局作用域,可以理解为 整个script标签内的作用域,就是全局作用域
-
全局变量都会挂载到 window 对象上
var num=100 var aaa=10000 /* 根据规则,这里是script标签内部,所以是全局作用域,我这个num */ //console.log(num) //100 //console.log(aaa) //10000 var name="千锋" //因为全局作用域window 上有一个属性叫name,所以我们的全局变量,要避免起名的时候叫做name,尤其是开发的时候 console.log(window)
-
-
局部作用域
-
在JS中,有且只有函数能够创建,局部作用域(函数作用域),局部作用域开始何结束位置,就是函数代码段开始和结束的位置
-
在局部作用域(函数作用域)内,声明的变量叫做局部变量
-
局部变量,不会挂载到window对象上
function fn(){ var num=100 console.log(num) //100 console.log(window)// }
-
-
以局部变量为荣,以全局变量为耻
-
什么是作用域链
-
变量的访问规则
变量访问会,现在当前作用域内查找,找到拿来直接用,如果过没有找到会去上层作用域查找;
如果上层作用域没找到,会继续上层作用域 的上层作用域内查找
var num=100 function fn(){ function fn1(){ console.log(num) } fn1() } fn() /* 首先在fn1 这个作用域内 访问变量 会在当前作用内查找num变量,如果访问不到,则返回上一层作用域查找 在fn 这个作用域内 访问变量 如果有则直接使用,没有返回上一层作用域 最后,在全局变量中,访问变量,查找变量num 找到了 num=100 故此,打印100 */
-
变量的赋值规则
-
变量赋值会先在当前作用域内查找,找到了直接拿来的赋值,如果没有,会去上层作用域内查找,找到了直接赋值;
-
如果上层作用域也没有找到,会继续区上层作用域 的啥高层作用域内找找,找到了直接赋值,没找到继续网上
-
如果找到了全局变量内,还是没有找到变量,那么会直接将变量定义为在当前作用域内(全局作用域),然后赋值
function fn() { function fn1() { num = 1000; } fn1() } fn() console.log(num) /* 首先访问 fn1这个作用域,给变量num赋值 那么会在当前的作用域查宅 */
-
-
在查找变量时,会在当前作用域,找到就用,就没找到上层找找,一直会查找到顶层作用域,(全局–window)
-
然后查找过程中,我们把逐层向上的一层一层查找,所构成的一个链条,叫做作用域链(实际是没有作用域链的,这是一个纯概念的东西)
-
**注意:**作用域链只会向上查找,不会向下
递归函数
-
在函数内部调用自己,调用自身。此时就是写了一种递归,但是死递归
-
要想写一个正确 的递归函数,需要在递归内部,写上,返回点(到某个条件是,停止递归)
function fn(){ if(满足条件){ fn() } if(不能满足条件1,满足条件2){ //结束递归函数 } }
-
斐波那数列
-
数列:1 1 2 3 5 8 13 21 34 55…
-
规则:前两位必须是1 ,从第二位开始,每一位是前两位的和
function cmx(n){ if(n ==1 || n==2){ return 1 } return cmx(n-1) + cmx(n-2) } var num=+prompt("请输入一个数字") var sum=cmx(num) console.log(sum);
-
Day06
对象
1、对象是什么?
是一种数据类型~复杂数据类型(引用数据类型)
函数—对象—数组 三个都是复杂数据类型
2、如何创建对象?
对象的创建分为两种
-
字面量形式创建
var obj={ } //声明一个变量obj,内部的值是一个空对象 var obj1={ //声明一个变量为obj1,内部的值是一个对象 //这个对象有个属性,属性名:name 属性值:'陈明旭' name:'陈明旭',//!!注意,这里是逗号(,)不是分号(;) age:18, un:undefined, boole:false 100:'1000'//正常来说,对象的key很少用数字命名 } console.log(obj1) //打印
对象内部通常存储的是以 键值对的形式存储
var obj={ name:'hello', age:18, } //name --->自定义的属性名(可以参考变量的命名规范,同时也接受以数字作为属性名) //'hellow' --->给对应的属性名 赋的值 //name 也可以叫做 key (和属性名 一个意思) //'hellow' 也可以叫做value(和属性值一个意思)
-
通过内置的构造函数
- 语法:
var obj=new Object() //new 后面要有空格,object首字母大写
-
内置构造函数
var obj=new Object() console.log(obj)
如何操作对象
-
点语法:
console.log(1111) //这就是一个点语法 var obj={ name:'张三', } //1.1 点语法 查 console.log(obj.name) //zhangsan console.log(obj.age) //undefined //1.2 点语法 增: obj.age=666 obj.abc=888 obj.zbc=999 console.log(obj) //1.3 点语法 改 obj.name ='lisi' console.log(obj.name) //lisi //1.4 点语法 删 delete obj.name console.log(obj) //{age:666}
-
中括号语法(数组语法)
var obj={ name:'zhangsan' } //2.1 中括号语法 查 console.log(obj['name'])//zhangsan //2.2 中括号语法 增 obj['age']=18 console.log(obj) //2.3 中括号语法 改 obj['name']='lisi' console.log(obj['name']) //2.4 中括号语法 删 delete obj['name'] console.log(obj)
-
中括号语法和点语法的区别
-
符合变量的命名规范或者规则,两者没有差异
-
如果不符合,那么就有差异,就比如数字 或者特殊符号,就只能通过,中括号语法
-
如果是变量相关的,只能使用 中括号语法
var obj={ name:'wangwu', 100:'qwer', '@':'df' } console.log(obj.name) //wangwu console.log(obj[name])//wangwu console.log(obj.100) //写法有误 console.log(obj[100])//qwer console.log(obj.@) //写法有误 console.log(obj.'@') //写法有误 console.log(obj['@'])//df var num='name' console.log(num) //name console.log(obj.name) //wangwu console.log(obj.num) //undefined //变量num代表的就是,‘name' 而obj.name 是可以
-
总结:正常使用的时候一般都是点语法居多,其它时候,比如需要用到变量的时候,必须使用中括号语法
-
循环遍历对象
可以通过for…in 循环 遍历对象,拿到对象的每一个 key(属性名)
1、语法:
for(var key in 对象名){
}
------------------------
var res={
name:'hello',
age:18,
un:undefined,
boole1:false,
boole2:true
}
for(var k in res){
console.log(k,res[k])
}
数组
1、什么是数组
- 字面含义:存放数字的,应该解释为:存放,一组数据的集合
- 和对象函数一样,数组也是引用数据类型
2、如何创建数组
-
字面量
var arr=[] //创建一个变量 内部存储一个空数组 var arr1=[1,'2',true,undefined] ------------------------------------------- var arr=[1,2,3,4,5] console.log(arr)
-
内置构造函数
var arr=new Array() ---------------------------- var arr1=new Array() //创建一个空数组 console.log(arr1) var arr2=new Array(1,2,3,4,5) //创建一个有值的数组 console.log(arr2) var arr3=new Array(10) //创建一个有长度的数组 console.log(arr3)
数组的长度
-
length:数组的长度
-
数组的长度,代表了数组内的成员数量,跟成员的值没有关系
var arr=new Array(); console.log(arr.length) var arr2=new Array(10) console.log(arr2.length) var arr3=new Array(1,2,3,4,5) console.log(arr3.length) //5 var arr4=[1,2,3] console.log(arr3.length) //3
什么是索引?
-
索引—>下标
-
就是一个数据,在这个数组huii中,那个位置(索引从0开始)
-
数组第一项,一定是 下标 0的
-
最后一项 一定是 数组的length -1
var arr=[1,2,3,4,5] //下标(索引号) 0 1 2 3 4 console.log(arr) console.log(arr[2]) //3 console.log(arr[arr.length-1])
遍历数组
var arr=[6,7,8,9,10]
arr.length-1 //-->代表 数组最好一位元素(成员)的下标
//for(var i=0;i<arr.length-1;i++)
for(var i=0;i<arr.length;i++){
//console.log(i)//0 1 2 3 4
console.log(arr[i]) //6 7 8 9 10
}
- 案例:给一个数组,求数组中数的累加和
var arr=[1,2,3,4,5]
var sum=0
for(var i=0;i<arr.length;i++){
sum+=arr[i]
}
console.log(sum)
-
案例二:找出数组中,最大值
var arr=[2,3,5,6,1,4] var max=0 for(var i=0; i<arr.length;i++){ if(max < arr[i]){ max=arr[i] } } console.log(max)
-
案例三 将数组第一位和第二位交换位置
var arr=[1,2,3] console.log('原数组:',arr); //[1,2,3] var temp=arr[0] //数组的第一项 保存到变量temp temp==1 arr[0]=arr[1]//数组的第二项,保存数组第一项值 arr[0]==2 arr[1]=temp //数组的第一项,保存temp的值 arr[1]==2 console.log('处理后:',arr); //[2,1,3]
-
案例四:冒泡排序
有1~100 这些数字,其中 某一位少了一个 比如没写59
//100 99 98 97 ... 5 4 3 2 1 //逻辑:一个数和他相邻数字的差值为1 //需求:将arr这个乱序数组,按照从很小到大的顺序排列 //处理后:[1,2,3,4,5,6,7,8,9] var arr=[3,2,8,7,9,5,4,6,1] for(var j = 0;j < arr.length-1;j++){ //外层循环不需要执行 for(var i=0;i<arr.length-1-j;i++){ if(arr[i]>arr[i+1]){ var temp=arr[i] arr[i]=arr[i+1] arr[i+1]=temp } } console.log(arr); }
数组的方法
常用方法1
-
push() 这个方法常用,但返回值不常用
-
语法:数组.push(要插入的数据)
-
作用:向数组的末尾 添加数据
-
返回值:追加数据后,数组最新的长度
var arr=[1,2,3] var num=arr.push(100) console.log(arr) //[1,2,3,100] console.log(num) //4
-
-
unshift
-
语法:数组.unshift(数据)
-
作用:向数组的开头,添加数据
-
返回值:追加数据后,数组最新的长度
var arr=[1,2,3] var num=arr.unshift(666) console.log(arr) //[666,1,2,3] console.log(num) //4
-
-
pop
-
语法:数组.pop()
-
作用:删除数组最后一条数据
-
返回值:被删除的数据
var arr=[1,2,3] var num=arr.pop() console.log(arr) //[1,2] console.log(num) //3
-
-
shift
-
语法:数组.shift()
-
作用:删除数组第一条数据
-
返回值:被删除的数据
var arr=[1,2,3] var num=arr.shift() console.log(arr) //[2,3] console.log(num) //1
-
作业
-
给出一个数组,将数组内所有值 放大100倍
//1.1 拿到数组的每一个成员(元素) //1.2 将每个成员 放大100倍 //1.3 将放大的数据,以数组的形式 打印在控制台 //var sum=[] var arr = [1,2,3,4] for(var i = 0; i<arr.length; i++){ // console.log(arr[i]*100) arr[i] *= 100 ==>arr[i] = arr[i] * 100 //sum.psuh(arr[i] * 100) }
-
给一个数组,然后给一个新值,将新值插入数据后 排序(按照从大到小)
var arr=[4,5,7,9,10,2]
arr.push(3)
for(var j = 0; j < arr.length -1 ; j ++){
for(var i = 0; i<arr.length -1 -j; i++){
if(arr[i] < arr[i + 1]){
var temp = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = temp
}
}
}
Day07
选择排序
- 逻辑:假设元素中数值最小的那一项为0,
- 然后找到数组中最小的那一项的下标,将其替换之前的记录的索引;
- 然后将两个位置的数据对换
var arr=[5,1,6,7,5,4,2,8,9,3] // 下标 0 1 2 3 4 5 6 7 8
/*
第几次循环 假设谁是对象 假设谁是最小值 循环开始
*/
for(var j=0;j<arr.length ;j++){
//1.假设数组中的第0个最小数字的索引
var minIndex = j
//2.遍历数组。找到数组中最小的那一项的下标,将其替换之前记录的下标
for(var i = j+1; i < arr.length ; i++){
if(arr[i] <arr[minIndex]){
minIndex=i
}
}
//console.log("循环处理后:" ,minIndex)
//3.遍历结束,找到最小的索引,将两个位置的数据 对换
var temp=arr[j]
arr[j]=arr[minIndex]
arr[minIndex] = temp
}
数组常用方法2
-
reverse
-
语法:数组.reverse()
-
作用:反转数组
-
返回值:反转后的数组
var arr=[1,2,3,4] var arr1=arr.reverse() console.log(arr1)//[4,3,2,1]
-
-
sort
-
语法:数组.sort()
- 参数
- 数组.sort(function(a,b){return a- b})
- 数组.sort(function(a,b){return b- a})
-
作用:根据参数 对数组数据 进行排序(可以从大到小,也可以反过来)
- 不传参数:会将数据转为字符串, 一位一位的对比
- 传参:
- 回调函数(其实就是传参的时候传入的 那个函数)内a-b 那么会按照数字 大小 升序排序
- 回调函数(其实就是传参的时候传入的 那个函数)内 b-a 那么会按照数字 大小 降序排序
-
返回值:排序后的数组
//1、不传参数 var arr=[3,5,1,2,2,100,250] var arr1=arr.sort() console.log(arr1) //2.1 传参 var arr2=arr.sort(function(a,b) { //return a-b 升序排序 //return b-a 降序排序 }) console.log(arr2)
-
-
splice(类似与剪切)
-
语法:
- 数组.splice(开始索引,多少个)
- 数组.splice(开始索引,多少个,插入数据1,插入数据2,插入数据3…)
-
作用:截取数组部分内容,并 选择性 插入数据
-
返回值:截取出来的部分内容组成的新数组
var arr = [3,2,1,4,5,100,1000,101] //var arr1 = arr.splice(1,3) //console.log(arr1) //[2,1,4] ---------------------------- var arr2=arr.splice(1,3,'n','w','e') console.log(arr2) //[2,1,4] console.log(arr) //[3,'n','w','e',100,1000,101]
-
-
slice(类似于复制)
-
语法:数组.slice(开始索引,结束索引)
- 包前不包后 包括开始索引,不包括结束索引
- 可以填写负整数,表示倒数第几个(其实就是length +负整数)
- 如果不传递第二个参数,默认是length
- 如果不传递第一个参数,默认是0
-
作用:复制数组的部分内容
-
返回值:复制出来的部分内容组成的新数组
var arr = [3,2,1,4,5,100,1000,101] var arr1 = arr.slice(1,3) console.log(arr1) //[2,1] ---------------------------- var arr2=arr.slice(1,-1) //-1相当于 length -1 console.log(arr2) //[2,1,4,5,100,1000] ---------------------------- var arr3=arr.slice(4)//如果不传递第二个参数,默认从开始下标复制数组的最后 console.log(arr4) //[5,100,1000,101] ---------------------------- var arr4=arr.slice() console.log(arr4) //[3,2,1,4,5,100,1000,101]
-
splice 和 slice 的差异(一定是高频面试题)
- 参数含义不同
- splice 相当于剪切,所以会改变原数组
- slice 相当于 复制,所以不会改变原数组
-
-
concat
-
语法:数组.concat(数组1,数组2,数组3,…)
-
作用:进行数据拼接,把参数的所有数组或数据,拼接到原始数组
-
返回值:拼接好的数组
var arr = [1,2,3] console.log('原始arr数据' + arr) var arr1 = arr.concat([4,5,6]) console.log('拼接好的arr1数据' + arr1)
-
-
join
-
语法:数组.join()
-
作用:使用连接符,把数组内的每一个数据拼接成一个字符串 连接符 根据参数来,不写(不传参数,默认为 , )
-
返回值:连接好的数据(字符串)
var arr = [1,2,3] console.log('原始数组' + arr) var arr1 = arr.join('+') console.log(arr1)
-
-
indexOf(O 是大写,不是小写)
-
语法:
- 数组.indexOf(要检查的数据)
- 数组.indexOf(要检查的数据,开始索引)
-
作用:从前到后 检查的数据 第一次 在该数组内的 索引
-
返回值:
- 如果找到了这个数据,返回第一次出现的索引
- 如果没找到 返回 -1
var arr = [1,2,3,3,2,1] console.log('原始数组arr数据',arr) var arr1 = arr.indexOf('2') console.log(arr1) //1(索引号) var arr2 = arr.indexOf(200) console.log(arr2) // -1(数组中没有找到200) var arr3 = arr.indexOf(2,2) console.log(arr3) //4(索引号)
-
-
lastIndexOf
-
语法:
- 数组.lastIndexOf(要检查的数据)
- 数组.lastIndexOf(要检查的数据,开始索引)
-
作用:从后向前 去查找。第一次数组内,出现的索引号位置
-
返回值:
- 如果找到了这个数据,返回第一次出现的索引
- 如果没找到 返回 -1
var arr = [1,2,3,3,2,1] var arr1 = arr.lastIndexOf(2) console.log(arr1) //4 var arr2 = arr.lastIndexOf(2,1) console.log(arr2) //1 var arr3 = arr.lastIndexOf(200) console.log(arr3) // -1
-
数组的遍历9种方法
-
forEach(在开发种,常用第一个参数 第二个参数看情况。 第三个参数 很少使用)
- 语法:arr.forEach(fucntion(item,index,o){})
- item :数组的每一项(数组的每一个值)
- index:数组每一项对应的下标
- o:原始数组
- 作用:遍历数组
- 返回值:没有返回值!!
var arr = [100,200,300,400,500] //for 循环遍历 for(var i=0;i<arr.length;i++){ console.log(arr[i]) } //forEach var arr1=arr.forEach(fucntion(item,index,o){ console.log(item)//100,200,300,400,500 console.log(index) //0,1,2,3,4 console.log(o) //[100,200,300,400,500] //return 100 写了return也不拥有返回值 }) console.log(arr1) //undefined ---------------------------------- arr.forEach(function(item){ console.log(item) }) ---------------------------------- arr.forEach(function(item,index){ console.log(item,index) })
- 语法:arr.forEach(fucntion(item,index,o){})
-
map
-
语法:arr.map(function(item,index,o){})
-
作用:映射数组
-
返回值:和数组长度一样的数组,只不过内部数据经过映射加工
var arr = [100,200,300,400,500] var arr1 = arr.map(function(item,index,o){ console.log(item,"在数组中的下标" ,index,'原始数组',o) return item/100 }) console.log("数组 arr1",arr1)//[1,2,3,4,5]
小案例:要求使用forEach 和map 完成两个版本
-
拿到数组的每一个值(用forEach map)
-
将他放大 100倍
-
以数组的形式。展示到控制台
var arr1=[] var arr = [1,2,3,4,5] //1、forEach arr.forEach(function(item,index){ //item 是数组的每一个值 但他是一个参数,修改他的值不影响数组 arr1.push(item*100) //arr[index]=item*100 }) console.log(arr1); //2、map var arr2=arr.map(function(item){ retrun item*100 }) console.log(arr2)
-
Day08
数组常用方法3
-
filter()
-
语法:数组.filter(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:对原始数组内数据进行过滤
-
注意:以return的形式书写,过滤条件
-
返回值:一个新的数组,
存放的是原始i数组内满足条件的那些内容
var arr=[] var res=arr.filter(fucntion(item){ return item>300 }) console.log("返回值",res)
-
-
find()
-
语法:数组.find(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:查找数组满足条件的第一个
-
注意:以return的形式书写 查找条件
-
返回值:
- 如果数组内有满足条件的数据,那么就是第一个满足条件的数据
- 如果数组内没有满足条件的数据,那么就是 undefined
var res=arr.find(function(item){ return item % 10 === 0 }) console,log('返回值',res)
-
-
findIndex()
-
语法:数组.findIndex(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:查找数组内满足条件的第一个数据的索引位置
-
注意:以return的形式书写 查找条件
-
返回值:
- 如果数组内满足条件的数据,那么就是第一个满足条件的数据所在的索引位置
- 如果数组内没有满足条件的数据,那么就是 -1
var res=arr.find(function(item){ return item % 10 === 0 }) console,log('返回值',res)
-
-
map()
-
语法:数组.map(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:映射数组;
对原始数据进行操作,返回一个操作以后的结果
-
注意:以return 的形式 书写 映射条件
-
返回值:是一个新数组
-
新数组的长度和原始数组一模一样
-
新数组内的数据是原始数组每一个数据操作过的样子
var res=arr.map(fucntion(item){ retrun item *10 }) console.log(res)
-
-
-
every()
-
语法:数组.every(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:判断数组内是否每一个都满足条件
-
返回值
- true:说明数组内所有项都满足条件
- false:说明数组内至少有一个不满足条件
-
注意:以return的 形式书写 判断条件
var res=arr.every(function(item){ return item < 100 }) console,log('返回值',res)
-
-
some
-
语法:数组.some(function(item, index, origin){})
- item:数组的每一项
- index:数组的索引
- origin:原始数组
-
作用:判断数组内是否有一个满足条件
-
注意:以return 的形式书写 判断条件
-
返回值:一个布尔值
- true:说明数组内至少有一个满足条件
- false:说明数组内所有数据都不满足条件
var res=arr.some(function(item){ return item > 400 }) console,log('返回值',res)
-
-
reduce()
-
语法:数组.reduce(函数 ,初始值)
- 函数:function(prev , item, index,origin){}
- prev:初始值或者上一次的计算结果
- 初始值:选填,不写的时候,默认使用数组的[0]位置数据当作初始值
- 函数:function(prev , item, index,origin){}
- 函数:function(prev,item,index,origin){}
-
-
作用:叠加
-
返回值:最终的叠加结果
-
注意:以return 的形式书写 叠加表达式
var res=arr.reduce(function(prev,item){ return prev + item },0) console,log('返回值',res)
数组塌陷
-
塌陷:当你删除数组中的数据,从删除位置向后的数据,索引会向前递进
-
困扰:但你删除以后,还要继续遍历数组的时候,会少东西
var arr = [100,200,300,400] console.log('初始数组',arr) for(var i=0; i<arr.length ;i++){ arr.splice(i,1) } console.log(arr)
-
解决:
-
方案1:不让数组塌陷,倒着循环数组
var arr = [100,200,300,400] console.log('初始数组',arr) for(var i=arr.length-1; i>=0 ;i--){ arr.splice(i,1) } console.log(arr)
-
方案2:退一步,i–
var arr = [100,200,300,400] console.log('初始数组',arr) for(var i=0; i<arr.length ;i++){ arr.splice(i,1) i-- } console.log(arr)
-
数组去重
-
目的:去除数组中的重复项
-
方案一
var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] console.log('原始数组',arr) /* 1、直接遍历 2、拿到当前这个,和当前以后进行比较,是否有一样的 3、只要有一样的,就干掉一个 */ for(var i=0 ;i<arr.length ;i++){ //当前这个:arr[i] //如何知道后面有没有了:indexOf(查找谁,从哪个索引开始) //查找谁 arr[i] //那开始 i+1 //如果后面找到了,返回值就是找到的哪个的数据的索引位置 //如果后买你没找到,返回值 -1 //只要不是 -1 ,就等于干掉了一个 var index= arr.indexOf(arr[i],i+1) if(index!==-1){ arr.splice(idnex,1) i-- } }
-
方案二
var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] /* 思路: 1、排序 */ arr.sort() //2、遍历 // 判断,当前这个 和下一个,只要一样,随便删除一个 for(var i=0; i<arr.length ;i++){ if(arr[i]==arr[i+1]){ arr.splice(i,1) i-- } } console.log('处理后的数组',arr)
-
方案三
/* 思路: 1、准备一个新数组 2、把原始数组内每一项一次插入到新数组中 判断,新数组内没有,才插入 */ var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] var newArr = [] for(var i=0 ;i<arr.length ;i++){ //拿到arr内的没有一准备插入的数据 if(newArr.indexOf(arr[i]) === -1){ newArr.push(arr[i]) } }
-
方案四
/* 思路: 1、创建一个对象 特点:键名不能重复,一样就是修改 特点:可以用纯数字当作键名 */ var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] var obj={ } //2、遍历原始数组,把每一个数据当作obj内的键名来使用 for(var i=0; i< arr.length ; i++){ var item =arr[i] //把item当作 obj 内的键名来使用 obj[item] ='cmx' } //把原始数组清空。 arr.length=0 //console.log("清空之后:",arr) //4、遍历obj。把每一个 键名依次 插入到arr 内 for(var k in obj){ arr.push(k-0) } console.log('去重之后:',arr)
-
方案五
var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] for(var i = 0; i< arr.length ; i++){ var index = arr.indexOf(arr[i], i+1) while(index !== -1){ arr.splice(index,1) //注意:因为重复的时候,如果 index 不变,那么就是死循环 //注意:因为重复的时候,如果 index 不变,那么就是死循环 //需要让,index 修改一下 index = arr.indexOf(arr[i] ,i+1) } }
-
方案六
/*利用 Set 数据结构 特点:不允许存储重复数据 语法:var s=new Set([数据1,数据2,数据3],...) var s=new Set([100,200,300]) console.log(s) */ var arr=[1,2,2,2,5,1,1,4,5,3,1,3,1,2] var s=new Set(arr) console.log(s) //2、把Set 数据结构还原成一个数组 //方法1:Array.from(数据) // 返回值:把该数据还原成一个数组 // var r1=Array.from(s) //console.log(r1) //方法2 使用 ... 运算符 展开运算符 // var r2=[... s] //console.log(r2) //书写: var r1 = Array.from(new Set(arr)) var r2 = [ ... new Set(arr)] console.log(r1) console.log(r2)
基本数据类型和复杂数据类型区别
-
存储:
- 基本数据类型:直接把值存储在 栈内存 里面
- 复杂数据类型(地址/引用数据类型):把数据放在堆内存存储,把数据地址放在栈内存中
-
赋值:
- 基本数据类型的赋值:就是直接值的复制,赋值完毕,两个变量没有关系
- 复杂数据类型的赋值:就是进行地址的复制,赋值完毕,两个变量操作一个存储空间
-
比较:
- 基本数据类型:进行值的比较
- 复杂数据类型:进行 地址的比较
var num =100 var str = 'hello' var obj = { name:"cmx"} //赋值 var n2=num console.log(n2,num) //100 100 n2= 200 console.log(n2,num) //200 100 var o2=obj console.log(o2,obj) //"cmx" "cmx" o2.name= 'hc' console.log(o2,obj) //'hc' 'hc' var o2={ name:"hc"} console.log(o2 === obj) //false
回调函数
- 一种调用方式
- 概念
- 把 函数A当作参数传递到函数B内
- 在函数B 内利用形参方式来调用函数A
- 我们管函数A 叫做函数B 的回调函数(callback)
- 使用:
- 需要封装 异步代码 的时候
- 需要封装 循环相关 的时候
Day09
认识字符串
-
是一个js内的基本数据类型 String
-
包装数据类型(了解)
- 在js内,字符串/布尔/数值。也是包装数据类型
- 平时存储时候,是按照基本数据类型存储
- 当你是用该数据的时候,会瞬间转换成复杂数据类型 的形式让你使用
- 当使用完毕,再次转换成基本数据类型的形式存储
-
创建
-
字面量方式
var s1 = 'hello' var s2 = "hello" console.log(s1) console.log(s2) console.log(s2 === s1)
-
内置构造函数方式
var s1 = 'hello' var s2 = "hello" var s3 = new String('hello') console.log(s3) console.log(s1 + 100) console.log(s2 + 100) console.log(s3 + 100)
-
-
结构
- 字符串内每一个内容也是按照 索引号进行 排列
- 索引: 从0开始。 依次 +1
-
ASCII(了解)
- ASCII是最早的字符集格式
- 只有128个字符
- 各个国家会推出自己国家的字符集编码(为了电脑再自己国家推广)
- 国标 GB2312 GBK
- 从前 128 个 就是 ASCII
- 从129 开始就是我们需要用到的中文
- Unicode 编码(万国码/统一码)
- 前128 个 ASCII 编码
- 后面按照顺序一次添加各个国家的文本
- 为了网络传输
- www 规定了一个要求,必须要用一个8位的 unicode 编码 作为网络传输编码格式
- 叫做 UTF-8
模板字符串
-
在2015 年拓展了一种定义字符串的方式
-
使用 反引号(``)定义字符串
- 管反引号(``)定义的字符串叫做 模板字符串
-
特点:
- 可以换行书写
- 可以直接在字符串内解析变量,当你需要解析的时候,书写 ${变量}
var str = '23' console.log(` 你好, 我叫陈明旭, 今年${ str}岁了, 我喜欢睡觉 `);
字符串的基本操作
-
length 属性
-
是一个只读的属性
-
读:字符串.length
- 得到:该字符串的长度,也就是该字符串的有多少少个字符组成
var str = 'hello world' console.log('原始字符串 : ', str) console.log(str.length) //尝试修改, 不能修改 str.length = 100 console.log(str) console.log(str.length)
-
-
索引属性
-
是一个只读的属性
-
读:字符串[索引]
- 得到
- 如果字符串有该索引位置,那么就是该索引位置的字符
- 如果字符串没有该索引位置,那么就是undefined
var str = 'hello world' console.log('原始字符串 : ', str) console.log(str[1]) console.log(str[100]) //尝试修改, 不能修改 str[1] = 'z' console.log(str) console.log(str[1])
- 得到
-
-
遍历
-
使用循环遍历字符串
-
因为字符串也是按照 索引排列
for (var i = 0; i < str.length; i++) { // 随着循环, i 分别表示 str 内每一个字符的索引 // 随着循环, str[i] 分别表示 str 内每一个字符 console.log(i, ' ---- ', str[i]) }
-
-
案例,统计字符出现字数
-
需求:拿到一个字符串,统计每一个字符出现多少次
-
例子:
- 原始字符串,’abcabc‘
- 最终的结果:a两次 b两次 c两次
-
问题:你准备如何保存统计结果?
-
保存结果的数据结果是 一个复杂数据类型
-
数组:
- []
- [‘a’,1,‘b’.1]
- [‘a’,1,‘b’,1,‘c’,1]
- [‘a’,1,‘b’,1,‘c’,1]
-
对象:
- {}
- {a:1}
- {a:1,b:1}
- {a:1,b:1,c:1}
var str = 'abcabc' console.log('原始字符串 : ', str) // 1. 准备一个空对象 var obj = { } // 2. 遍历字符串开始统计 for (var i = 0; i < str.length; i++) { var item = str[i] // 三元表达式 obj[item] ? obj[item]++ : obj[item] = 1 /* if(obj[item]){ obj[item]++ } else{ obj[item] = 1 } */ } console.log(obj)
-
-
字符串常用方法
-
注意:所有字符串方法,都不会改变原始字符串,以返回值给出结果
-
chartAt()
-
语法:字符串.chartAt(索引)
-
返回值:
- 如果字符串内有该索引位置,那么就是该索引位置的字符
- 如果字符串没有该索引位置,那么就是 空字符串(’”)
str = 'hello world' console.log(str) var res = str.chartAt(1) console.log(res) //e
-
-
charCodeAt()
-
语法:字符串.charCodeAt(索引)
-
返回值:
- 如果字符串内有该索引位置,那么就是该索引字符的 编码(unicode)
- 如果字符串内没有该索引位置,那么就是 NaN
var res = str.charCodeAt(1) console.log(res)
-
-
toUpperCase()
-
语法:字符串.toUpperCase()
-
返回值:原始字符串内所有字母转换成大写以后的结果
var res = str.toUpperCase() console.log(res)
-
-
toLowerCase()
-
语法:字符串.toLowerCase
-
返回值:原始字符串内所有字母转成大写以后的结果
var res = str.toLowerCase() console.log(res)
-
-
substr()
-
语法:字符串.substr(开始索引,多少个)
-
返回值:截取出来的部分字符串
//表示 从[2] 开始 ,向后截取 7 个字位置的内容 var res = str.substr(2,7) console.log(res)
-
-
substring()
-
语法:字符串.substring(开始索引,结束索引)
-
返回值:截取出来的部分字符串
-
特点:包前不包后
//表示从 [2] 截取到 [7],包含 [2] 位置字符,不包含[7] 位置字符 var res = str.substring(2,7) console.log(res)
-
-
slice()
-
语法:字符串.slice(开始索引,结束索引)
-
返回值:截取出来的部分字符串
-
特点:包前不包后,填写负整数
//表示从 [2] 截取到 [7],包含 [2] 位置字符,不包含[7] 位置字符 var res = str.slice(-9, -4) // -4 等价于 str.length + -4 console.log(res)
-
-
replace()
-
语法:字符串.repalce(换下字符,换上字符)
-
作用:在原始字符串内使用 换上字符 替换掉 换下字符
-
注意:值能替换出现一个
-
返回值:替换好的字符串
//把str 字符串 的 ** 第一个** ’1‘ 字符替换成’*‘ var res = str.replace('1','*') console.log(res)
-
-
split()
-
语法:字符串.split(分隔符)
-
作用:按照分隔符把字符串分隔分开
-
返回值:一个数组
该数组内是把原始字符串按照分隔符分开的每一个部分
var str = '2022-10-3' // 表示使用 '-' 把 str 分隔成 若干个 部分 var res = str.split('-') // 如果填写的是 '', 那么按照索引逐位分开 var res = str.split('') console.log(res)
-
-
indexOf()
-
语法:字符串.indexOf(检测的字符段片段,开始索引)
-
返回值:
- 如果原始字符串内有该字符串片段,那么就是该字符片段的开始索引
- 如果原始字符串内没有该字符串片段,那么就是 -1
var res = str.indexOf('l', 5) console.log(res)
-
-
lastIndexOf()
-
语法:字符串.lastIndexOf(检测的字符段片段,开始索引)
-
返回值:
- 如果原始字符串内有该字符串片段,那么就是该字符片段的开始索引
- 如果原始字符串内没有该字符串片段,那么就是 -1
-
注意:从后向前检索
var res = str.lastIndexOf('l', 8) console.log(res)
-
-
concat()
-
语法:原始字符串.concat(字符串1,字符串2,字符串3,…)
-
返回值:拼接好的字符串
var str = ' hello world ' console.log(str)
-
-
trim()
-
语法:原始字符串.trim()
-
返回值:去除原始字符串内收首尾空格后的结果
var res = str.trim() console.log('trim : ', res)
-
-
trimStart()/trimLeft()
-
语法:
- 字符串.trimStart()
- 字符串.trimLeft()
-
返回值:去除原始字符串内开始位置空格的结果
var res = str.trimStart() var res = str.trimLeft() console.log('trimStart : ', res)
-
-
trimEnd() / trimRight()
-
语法:
- 字符串.trimEnd()
- 字符串.trimRight()
-
返回值:去除原始字符串内结束位置空格的结果
var res = str.trimEnd() var res = str.trimRight() console.log('trimEnd : ', res)
-
-
一些不常用的方法
var str = 'hello world' document.write(str) document.write('<br>') fontcolor var res = str.fontcolor('red') fontsize var res = str.fontsize('100').fontcolor('red') var res = str.fontsize('100').fontcolor('red').bold().italics() document.write(res)
字符串小练习
-
反转字符串
-
方案一
//提前准备一个变结果 var str = 'abcdefg' var res='' for(var i = str.length - 1; i >= 0 ;i--){ res+=str[i] } console.log(res); //提前准备一个变结果 var str = 'abcdefg' var res='' for(var i = 0; i < arr.length ;i++){ res = str[i] +res } console.log(res);
-
方案二
var str = 'abcdefg' // reverse() 反转数组 // reverse 可以实现反转效果, 但是只能反转数组 // 如果想用 reverse 方法, 需要把 str 转换成 数组 // [ 'a', 'b', 'c', ... ] // split() 切割字符串, 如果传递的参数是 空字符串('') 按照位一位一位切割开 // var r1 = str.split('') // console.log(r1) // // 此时 r1 就是一个数组了, 我们需要使用 reverse 方法反转 r1 这个数组 // var r2 = r1.reverse() // console.log(r2) // // 此时只要把 r2 内的每一个内容连接起来就可以了 // // join() 把数组连接成字符串 // var res = r2.join('') // console.log(res) var res = str.split('').reverse().join('')
-
-
敏感词替换
-
方案一
var str = 'hjHHsdHHgfjHHhsaHHdgf' while(str.indexOf("HH") !== -1 ){ str=str.replace("HH","**") console.log(str); } console.log(str);
-
方案二
var str = 'hjHHsdHHgfjHHhsaHHdgf' var res = str.split(s).join('**') console.log(res)
-
-
批量敏感词替换
var str = 'hCCjHHsNNdHHgfNNjHHhsMMaHHdgf' var arr = [ 'HH', 'NN', 'MM', 'CC' ] for(var i = 0;i < arr.length ;i++ ){ str=str.split(arr[i]).join('**') } console.log(str) ----------------------------- // 遍历 list 数组依次执行 // list.forEach(function (item) { // // item 是数组内的每一项 // str = str.split(item).join('**') // })
字符串类型
-
Js 内,对字符串进行了一些区分(人为)
- 普通字符串 ==> ‘asdasdasdadsasdasdaads’
- 数字字符串 ==> ‘12345132185’
- html格式字符串 ==>
‘<span> asd</span>’
- 查询字符串(querystring)==>‘key=value&key2=value2’
- & 分开了多少条数据
- = 分开了每一条数据的 键 和值
-
查询字符串
-
如何把 对象数据结构 转换成 查询字符串
var obj={ name:'Jack',age:18,gender:'男'} //结果:'name=Jack&age=18&gender=男' //提前准备一个字符串,接受拼接结果 var str = '' //循环遍历对象 for( var k in obj){ str += `${ k}=${ obj[k]}&` } //去掉最后一位 str = str.splice(0,-1) console.log('处理结果是:',str)
-
如何把 查询字符串 转换成 对象数据结构
//定义一个字符串 var str ='name=Jack&age=18&gender=男' //定义一个对象 var o={ } //使用'&'把str 字符串 分割成数组 var temp = str.split('&') //遍历 temp 新数组,每次向obj 内添加一个成员 temp.forEach(function(item){ //item是 temp内的每一个值 var t = item.splict('=') o[ t[0] ] = t[1] }) console.log(o)
-
-
json 字符串
-
json格式字符串
- ‘{“name”:“Jack”,“age”:18}’
- ‘[{“name”:“cmx”},{“name”:“cmx”}]’
- 要求:key 和 value 必须被双引号包裹,数字和布尔除外
-
把JS数据结构,转换成json格式字符串
//语法:JSON.stringify(JS的数据结构) //返回值:一个合法的 json 格式字符串 var obj={ name:'Jack',age:22,gender:'男'} console.log(typeof obj) //object //把 obj 转成json 格式字符串 var str = JSON.stringify(obj) console.log(str) console.log(typeof str) //string
-
把 json 格式化字符串 ,转换成 JS的数据结构
//语法:JSON.parse(json格式字符串) var str = '{"name":"cmx","age":18,"gender":"男"}' console.log(typeof str) //string //把字符串 str 当作json 格式化字符串转换成JS的数据结构 var obj=JOSN.parse(obj) console,log(obj) console.log(typeof obj)//object
-
Day10
数学常用方法
-
一系列操作数字的方法:
-
random()
-
语法:Math.random()
-
返回值:一个 0~1之间 的随机数,有可能包含0 但是绝不肯能包含1
console.log(Math.random())//0~1随机数
-
-
round()
-
语法:Math.round()
-
返回值:对该数字进行四舍五入取整以后的结果
//正整数 console.log(Math.round(10.4)) //10 console.log(Math.round(10.5))//11 console.log(Math.round(10.4.999)) //10 /* 整数部分:小于自己的最大整数 小数部分:整数部分到自己的距离 -10.4 整数部分:-11 小数部分:0.6 */ console.log(Math.round(-10.4))//-10 console.log(Math.round(-10.5))//-10 console.log(Math.round(-10.6))//-11
-
-
ceil()
-
语法:Math.ceil(数字)
-
返回值:对该数字进行向上取整以后的结果
console.log(Math.ceil(10.5)) //11 console.log(Math.ceil(10.1))//11
-
-
floor()
-
语法:Math.floor(数字)
-
返回值:对该数字进行向下取整以后的结果
console.log(Math.floor(10.5))//10 console.log(Math.floor(10.1)) //10
-
-
abs()
-
语法:Math.abs()
-
返回值:该数字的绝对值
console.log(Math.abs(-10)) //10
-
-
pow()
-
语法:
- math.pow(底数,指数)
- Math.pow(谁,的多少次)
-
返回值:取幂结果
console.log(Math.pow(27, 1/3)) //2 console.log(Math.pow(2, 3))//8
-
-
sqrt()
-
语法:Math.sqrt()
-
返回值:该数字的算数平方根
console.log(Math.sqrt(9)) //3
-
-
max()
-
语法:Math.max(数字1,数字2,数字3,…)
-
返回值:若干个数字内的最大值
console.log(Math.max(10, 20, 30, 22, 11, -7, 3, 4)) //30
-
-
min()
-
语法:Math.min(数字1,数字2,数字3,…)
-
返回值:若干个数字内的最小值
console.log(Math.min(10, 20, 30, 22, 11, -7, 3, 4)) //-7
-
-
PI
-
语法:Math.PI
-
得到:一个近似Π的值
console.log(Math.PI) //3.14159265354579
-
保留小数
-
语法:数字.toFixed(你要保留多少位的小数)
-
返回值:以 字符串 的形式返回保留好的小数位的数字,小数位不够的时候用 0 补
var n = 10.23456789 var res = n.toFixed(3) console.log(res)//10.235
转换进制数(了解)
十进制转换成其他进制
-
语法:数字.toString(你要转换的进制数)
-
返回值:以字符串的形式返回转换好的进制数字
-
参数范围:2~36
var n = 8 var res = m.toString(16) console.log(res)
其他进制数字转换成十进制
-
语法:parseInt(你要转换的数字,你把这个数字当作几进制)
-
返回值:转换好的十进制数字,数值类型
var n = 100 //把 n 这个数字当做一个 二进制 数字,转换成十进制数字 var res = paresInt("ff",16) console.log(res)
进制:
/*
十进制:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
八进制:0 1 2 3 4 5 6 7 8 10 11 12 13 14 15 16
二进制:0 1 10 11 100 101 111 1000
十六进制:0 1 2 3 4 5 6 7 8 9 a b c d e f
*/
范围内的随机整数
-
封装一个函数,求 x~y 之间的随机整数
-
求一个 0~(大 - 小)之间的随机整数
-
用这个这个随机整数 + 小
-
分析:
10 ~ 20 0 ~ 10 + 10 20 ~ 30 0 ~ 10 + 20 10 ~ 30 0 ~ 20 + 10 function randomNum(x,y){ //1、求出两数差 var sub = Math.abs(y - x) //2、求出 0 ~ sub 之间的随机整数 var r1 = Math.floor(Math.random() * (sub +1)) //3、用 r1 加上 相对小的 那个数字 var res = r1 + Math.min(x,y) return res } var res = randomNum() console.log(res)
-
-
写一段验证代码
10000000 个随机数字, 统计每一个随机数字出现的次数
var obj = { } for(var i = 0; i < 10000000; i++){ var res = fn(22,36) if(obj[res]){ obj[res]++ }else{ obj[res] = 1 } } console.log(obj)
-
应用题:
-
已知:一个数字 向下 取整以后是10
- 这个数字的范围有可能是多少? 10 ~ 10.999
-
已知:一个数字向下取整数以后是 9
- 这个数字的范围有可能是多少? 9 ~ 9.999
-
已知:一个数字向下取整以后是 0 ~ 10
- 这个数字的范围有数字的范围扩大到 0 ~ 10.999
-
已知:一个数字是一个随机数 的小数,0 ~ 0.999 之间
- 如何能把这个数字的范围扩大到 0 ~ 10.999 之间? 该数字 +11
-
封装一个函数,获取一个随机颜色字符串 rgb 形式
方案一:
/* function randomColor(){ //code run here... } 将来使用的时候 var res = randomColor() res 得到的就是 'rab(数字,数字,数字)' */ function randomColor(){ //生成一个 rgb 形式的随机颜色字符串 var r = randomNum(0,255) var g = randomNum(0,255) var b = randomNum(0,255) var color = `rgb(${ r },${ g },${ b })` //把生成好的字符串返回 retrun color }
方案二:
function randomColor(){ //准备一个数组,存储颜色字符串 var colors = [] for(var i = 0; i < 3; i++ ){ colors.push(randomNum(0,255)) } //连接字符串 var color = `rgb(${ colors.join(',')})` //把生成的字符串返回 return color } var res = randomColor() console.log(res)
-
封装函数,获取一个随机数颜色字符串 十六进制形式
方案一
/* function randomColor(){ code run here... } //将来使用的时候 var res = randomCOlor() res 得到得就是 '#F53E42' */ function randomColor(){ //1、准备一个原始字符串 var color = "#" //循环生成 for(var i = 0; i < 3; i++){ //2-1.生成一个 0~255的随机数 //随机数是可能拿到 0 ~ 15 的,转换成16 进制以后,是00 01 02 03 04 05 6 7 8 9 var n = randomNum(0,255) //2-2. 把转换成 十六进制 var s = n.toStirng(16) //2-3. 判断一下,如果 n <= 15,那么 s 的前面需要补一个 '0' if(n <= 15){ s= "0" + s } //2-4 把每一个 s 依次拼接到 color 上 color += s } //3. 返回结果 return color }
方案二
function randomColor(){ //1.准备一个序列 ,里面包含了 0 1 2 3 4 5 6 7 8 9 a b c d e f //var list = '0123456789abcdef' //2、准备变量接受结果 var color = '#' //3、重复生成 for(var i = 0; i < 6; i++){ //3.1 生成一个随机索引 var index = randomNum(0,15) var s = index.toString(16) //组装 color += s } return color } var res = randomColor() console.log(res) //#xxxxxx
-
生成随机验证码
-
生成一随机的四位验证码(出数字)
-
方案一:
var code = randomNum(1000,9999)//randomNum为自己封装的随机数函数,以下均是 console.log(code)
-
方案二:
var code = "" for(var i = 0;i < 4;i++){ code += randomNum(0,9) } console.log(code)
-
方案三:
var code = Math.random().toString().slice(-4) console.log(code)
-
-
生成一个随机的四位数验证码(包含数字和字母)
//需要一个序列 var list = '0123456789abcdefghijklmnopqrstuvwxyz' //准备变量接受结果 var code = '’ for(var i=0; i < 4;i++){ //准备 0 ~25 之间 的随机数字 var index = randomNum(0,35) //用 index 当做索引,去访问字符串 var s = list[index] code += s } console.log(code)
-
生成一个随机的四位数验证码
-
可以包含数字和字母
-
不允许出现重复内容
//准备空字符串接受结果 var code = '' //循环 for(var i = 0; i < 4; i++){ //生成一个随机的内容 var s = randomNum(0,35).toString(36) //把 s 拼接到code 身上 //注意:需要判断一下,如果code 内没有这个字符,才拼接 if(code.indexOf(s) === -1){ code += s } else{ i-- } //code.indexOf(s) === -1 ? code +=s :i-- 三元表达式 意义同上 } console.log(code)
-
时间对象:
-
认识时间对象
- 是JS内的一个复杂数据类型,叫做 Date
- 专门用来存储时间相关信息的
-
创建时间对象
- 内置构造函数方式
- 语法:var time = new Date()
- 得到:当前终端的时间
-
创建指定之间节点的时间对象
-
语法:var time = new Date(参数)
var time = new Date() console.log(time) console.log(typeof time) //object
-
传递数字:
-
传递一个数字
-
该数字表示 毫秒数
-
表示从 格林威治时间 向后顺延的毫秒数
//表示创建的是从 格林威治时间 向后顺延 1000ms 的时间节点 var time = new Date(86400000) console.log(time)
-
-
传递多个数字
-
多个数字分别表示 年 月 日 时 分 秒 毫秒
-
注意:月份位置 0 表示 1 月,11 表示 12 月
-
注意:所有时间信息位置都是可以自动进位的
var time = new Date(2005,11,31,23,59,59,999+1) console.log(time)
-
-
传递字符串
-
’YYYY-MM-DD HH-mm:ss‘
-
‘YYYY/MMMM/DD HH:mm:ss’
-
注意:年月日和时分秒之间有一个空格
-
注意:月份位置,1 表示 1月,12月表示 12 月
//1、 var time = new Date("2008-8-8 20:00:00") //Fri Aug 08 2008 20:00:00 GMT+0800 //2、 var time = new Date('2008/8/8 20:00:00')//Fri Aug 08 2008 20:00:00 GMT+0800 console.log(time)
-
-
格林威治时间(计算机元年)
- 1970 年 1 月 1日 0 点 0 分 0 秒 0毫秒
-
-
时间对象的常用方法
获取方法
-
getFullYear()
-
语法:时间对象内的 年份信息
-
返回值:该时间对象内的 年份信息
var year = time.getFullYear() console.log(year)
-
-
getMonth()
-
语法:时间对象.getMonth()
-
返回值:该时间对象.getMonth()
-
注意:0 表示 1 月 ,11 表示 12 月
var month = time.getMonth() console.log(month)
-
-
getDate()
-
语法:时间对象.getDate()
-
返回值:该时间对象内的 日期信息
var date = time.getDate console.log(date)
-
-
getHours()
-
语法:时间对象.getHours()
-
返回值:该时间对象内的 小时信息
var hours = time.getHours() console.log(hours)
-
-
getMinutes()
-
语法:时间对象.getMinutes()
-
返回值:该时间对象内的 分钟信息
var minutes = time.getMinutes() conseloe.log(minutes)
-
-
getSeconds()
-
语法:时间对象.getSeconds()
-
返回值:该时间对象内的 秒钟信息
var seconds = time.getSeconds() console.log(seconds)
-
-
getMilliseconds()
-
语法:时间对象.getMilliseconds()
-
返回值:该时间对象内的 毫秒信息
var ms = time.getMilliseconds() console.log(ms)
-
-
getDay()
-
语法:时间对象.getDay()
-
返回值:该时间对象内的 星期信息
-
注意:0 表示 周日 1~6 表示 周一 ~周六
var week = time,getDay() console.log(week)
-
-
getTime()
-
语法:时间对象,getTime()
-
返回值:该时间对象内的 时间戳 信息
-
时间戳:从 格林威治时间 到 该时间节点 的毫秒数
var t = time.getTime() console.log(t)
-
设置方法
-
setFullYear()
-
语法:时间对象.getFullYear(年份数字)
-
设置该时间内的年份信息
time.setFullYear(2008) consloe.log(time)
-
-
setMonth()
-
语法:时间对象.setMonth(月份数字)
-
注意:0 表示 1 月,11 表示 12 月
-
设置该时间对象内的月份信息
time.setMonth(6) console.log(time)
-
-
setDate()
-
语法:时间对象.getDate(日期信息)
-
设置该时间对象内的日期信息
time.setDate(22) console.log(time)
-
-
setHours()
-
语法:时间对象.getDate(日期信息)
-
设置该时间对象内日期信息
time.setDate(22) console.log(time)
-
-
setSeconds()
-
语法:时间对象.setSeconds(秒钟数字)
-
设置该时间对象内秒种信息
time.setSeconds(55) console.log(time)
-
-
setMilliseconds()
-
语法:时间对象.setMilliseconds(毫秒数字)
-
设置该时间对象内的毫秒信息
time.setMilliseconds(789) console.log(time.getMilliseconds())
-
-
setTime()
-
语法:时间对象.setTime(时间戳信息)
-
直接使用时间戳来定义时间节点
time.setTime(5000) console.log(time)
-
获取时间差
-
最终:目的函数,获取两个时间节点之间的时间差
-
问题1:是否需要参数?
需要两个参数,分别是 两次时间节点
-
问题2:是否需要返回值 ?
-
需要一个返回值
-
需要一个能包含四个信息的返回值,四个信息分别是 天 小时 分钟 秒钟
-
要么返回一个数组:[ 1, 2, 3, 4, ]
-
要么返回一个对象:{day:xxx,hours:xxx,minutes:xxx,seconds:xxx}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; } div { width: 700px; height: 200px; font-size: 50px; line-height: 100px; text-align: center; position: fixed; top: 0; left: 0; right: 0; bottom: 0; margin: auto; font-weight: 700; background-color: #ccc; color: #ccc; text-shadow: 1px 1px 0 #333, -1px -1px 0 #fff; } </style> </head> <body> <script> function diffTime(start,end){ //1、计算出相差的毫秒 //结束时间节点的时间戳 - 开始节点的时间戳 //顺便换算成秒 var sub = Math.ceil((end.getTime() - start.get.getTime()) / 1000) //console.log(sub) //2、换算 //2.1 换算天 var day = parseInt(sub / (60 *60 *24)) //console.log(day) //2.2 换算小时 var hours = parseInt(sub / (60 * 60 * 24) / (60 * 60)) //console.log(day) //2.3 换算分种 var minutes = parseInt(sub % (60 * 60 ) / 60) //console.log(minutes) //2.4 换算秒钟 var seconds = sub % 60 //console.log(seconds) //3、组装一个对象 var obj = { day:day, hours:hours, minutes:minutes, seconds:seconds } //4、返回这个对象 return obj } // 将来我们使用的时候 var t1 = new Date() var t2 = new Date('2022-12-31 23:59:59') var res = diffTime(t1,t2) document.write(` <div> 距离过年还有:<br> <span>${ res.day} 天 ${ res.hours} 时 ${ res.minutes} 分 ${ res.seconds} 秒</span> </div> `) </script> </body> </html>
-
Day11
定时器:
-
定时器:
- 浏览器提供的一个 JS 内异步执行代码的机制
- 异步与非异步:
- 非异步(同步):JS 执行代码的基本原则
- 从上到下从左到右依次执行代码
- 从上面一行代码没有执行完毕,下面一行代码等待
- 异步:当JS 代码在执行过程中遇到异步代码的时候
- 不会执行该异步内容,而是把该异步内容放在 队列 内等待
- 继续向下执行同步代码
- 等待所有同步代码执行完毕
- 再来队列内执行异步代码
- 非异步(同步):JS 执行代码的基本原则
-
开启定时器
-
延时定时器:
- 语法:setTimeout(函数,数字)
- 作用:在指定时间以后,执行一遍函数
- 函数:在一段时间内以后执行的代码
- 数字:单位时毫秒,表示在多少时间以后
setTimeout(function(){ console.log('啦啦啦啦') },1000) //1000毫秒
-
间隔定时器
-
语法:setInterval(函数,数字)
-
作用:每间隔一段时间,执行一遍函数
-
函数:需要执行的代码
-
数字:单位是毫秒,表示间隔多少时间
setInterval(function(){ //该函数每间隔 1000ms 会执行一次 console.log(new date) },1000)
-
-
-
定时器的返回值
-
不区分定时种类
-
返回值就是一个数字,表示你是页面上的第几个定时器
-
作用:用来关闭定时器使用的
var t1 = setTimeout(function(){ },1000) var t2 = setInterval(funciton(){ },1000) console.log('t1:',t1,typeof t1) //t1:1 number console.log("t2:",t2,typeof t2)t2:2 number
-
-
关闭定时器
-
不区分定时器种类,只要给出的定时器返回值时对的,就可以关闭定时器
-
语法:
- clearTimeout(定时器返回值)
- clearInterval(定时器返回值)
var t1 = setTimeout(function(){ },1000) var t2 = setInterval(function(){ },1000) //为了观察方便,把关闭定时器的代码书在一个 按钮的点击事件内 //在H5标准中,一个元素的id 名 可以在js内当作天生变量使用 //元素.onclick = function () {} //给元素绑定一个鼠标点击事件,当你单机该元素的时候,触发该函数 btn.onclick = function() { //该函数会在你点击页面上 id = "btn" 那个元素的时候触发 //执行关闭定时器的代码 //clearTimeout(t1) //clearTimeout(t2) clearInterval(t1) clearIntrval(t2) }
-
-
观察异步执行代码:
console.log("start") setTime(function(){ console.log("我是定时器") }) console.log("end") /* 输出顺序: 1、start 2、end 3、我是定时器 */
定时器案例
倒计时
-
分析:
- 把间隔 1000ms 获取一次 当前时间 和 目标是时间 之间的时间差
- 把时间渲染页面的指定位置
- 在这个个过程中:
- 每间隔 1000ms 是否需要获取一次当前时间
- 每间隔 1000ms 是否需要获取一次目标时间
//获取目标时间 var target = new Date("2022-10-14 12:15:00") //每间隔 1000ms 执行一次代码 var timer = setInterval(function () { //获取当前时间 var currnet = new Date() //获取当前时间和目标的时间差 var res = diffTime(current,target) //diffTime为封装好的时间差函数 详情看案例:时间差 //组装一个内容插入到页面上 var str = `距离下课时间还有:${ res.day} 天 ${ res.hours } 小时 ${ res.minutes } 分钟 ${ res.seconds } 秒钟` //把str 输出在页面上 //语法:元素.innerText = 值 box.innerText = str //判断 if(res.day === 0 && res.hours === 0 && res.minutes === 0 && res.seconds ===0){ clearInerval(timer) } },1000)
验证码按钮
-
分析:
- 当你点击按钮以后出现效果
- 文本修改为’再次获取(5s)’
- 每间隔 1s 修改 一次文本内容
- 等到时间到 0s 的时候,文本还还原成 ‘“点击获取验证码”
-
抖动问题
- 原因:
- 再一次的"动效" 没有 完成之前 ,进行了多次点击
- 导致的”动效“重叠,出现的抖动效果
- 解决:
- 第一次点击的时候,可以出现"动效"
- 在第一次的“动效” 结束以前,多次点击不执行任何代码
- 问题1:如何内让函数内的某些代码不执行?
- return,写在retrun 关键字后面的代码不执行了
//准备一个变量当作开关 var flag = true //1、绑定点击行为 btn.onclick = function () { //判断是否会后续的代码执行 //如果 flag 是 true,继续执行后续代码 //如果 flag 是 flase,后续代码不在执行了 if(flag === flase) return //代码能执行到这里,说明flag 是什么 true ,马上就会开启一个“动效” flag = false //2、修改一次文本内容 btn.innerText = "再次获取(5s)" //3、每间隔 1s 修改一次文本内容 //3.1 准备一个初始值 var count = 5 //3.2 开启定时器 var timer = setInterval(function(){ //3.3 修改初始值 count-- //3.4 修改一次 btn 的 文本内容 btn.innerText = `再次获取(${ count})` //3.5 判断当 count 为 0 的时候还原 if(count <= 0){ //关闭定时器 clearinterval(timer) //还原文本 btn.innerText = '点击获取验证码' //上一次的“动效” 执行完毕了 flag = true } },1000) }
- 原因:
认识BOM
- BOM(Browser Object Model) 浏览器对象模型
- 私人:一整套操作, 浏览器相关内容 的属性和方法
- 特点:
- 由浏览器提供的 属性 和方法
- 在不同的浏览器内表现的形式不一样
- 在不同的浏览器的兼容情况不一样
- 语法:基本上都是 window.xxx,在书写的时候可以省略 widow 不写
- 例子:弹出层
- 标准语法:widow.alert()
- 书写:alert()
- 操作部分
- 弹出层
- 历史记录
- 地址栏
- 标签页
- 滚动条
- …
浏览器的可视窗口尺寸
-
语法:
- 宽度:window.innerWidth
- 高度:window.innerHeight
-
注意:获取到的尺寸是包含滚动条内的尺寸
console.log('宽度:',window.innerWidth,innerWidth) console.log('高度:',window.innerHeight,innerHeight)
浏览器的弹出层
-
提示框
-
语法:window.alert(“提示文本”)
-
表现:一段提示文本 + 确定按钮
-
返回值:undefined
var res = window.alert("你好 世界") console.log(res)
-
-
询问框
-
语法:window.confirm(‘提示文本’)
-
表现:在 提示 框的基础上 + 取消按钮
-
返回值:一个布尔值
- 如果用户点击的是确定按钮,返回 true
- 如果用户点击的是取消按钮 ,返回 false
var res = window.confirm("您确定要删除该信息吗") console.log(res)
-
-
输入框
-
语法:window.prompt(“提示文本”)
-
表现:在输入框的基础上 + 文本框
-
返回值:
-
如果用户点击的是取消按钮,那么就是 null
-
如果用户点击 的是确定按钮,那么就是 文本框的内容(如果没有输入 的就是 空字符串)
注意:拿到的值是一个字符串类型,哪怕输入的数字,也是字符串的类型
var res = window.prompt("请输入密码") console.log(res) console.log(typeof res)
-
-
浏览器的常见事件
-
依赖浏览器的行为而触发的事件
-
load
-
语法:window.onload =function () {}
-
时机:当前页面所有资源(htm,css, js, 图片, 视频,音频,等 ) 记载完毕后触发
-
常用:
- 当你在body 内书写js代码的时候,并且操作了页面元素的时候
window.onload = function(){ console.log("所有资源加载完毕了") }
-
-
resize:
-
语法:window.onresize = function () {}
-
时机:当前页面可视窗口尺寸改变的时候触发(不管横向还是纵向,只要改变就会触发,一直改变一直触发)
-
常用:一般用来捕获横屏
window.onresize = function (){ console.log('可视窗口尺寸在改变') var w = window.innerWidth if(w >= 768 ) alert("竖屏游戏体验更佳") }
-
-
scroll
-
语法:window.onscroll = function () {}
-
时机:浏览器滚动条滚动的时候触发(不管横向还是纵向,只要改变就会触发,一直改变一直触发
window.onscroll = function () { consolr.log("滚动中"}
-
浏览器卷去的尺寸(滚动条定位)
-
卷去的高度:
- 语法:
- document.documentElement.scrollTop
- 当前页面有 DOCTYPE 标签的时候能获取到尺寸
- document.body.scrollTop
- 当前页面没有 DOCTYPE 标签的时候能获取到尺寸
- document.documentElement.scrollTop
- 兼容
- var 自己定义一个变量 = document.documentElement.scrollTop || document.body.scrollTop
- 语法:
-
卷去的宽度
- 语法:
- document.documentElement.scrollLeft
- 当前页面有 DOCTYPE 标签 的时候能获取到尺寸
- document.body.scrollLeft
- 当前页面没有DOCTYPE标签的时候能获取到尺寸
- document.documentElement.scrollLeft
- 兼容:
- var 自己的定义一个变量 = document.documentElement.scrollLeft || document.body.scrollLeft
//为了方便观看,把该代码书写在浏览器滚动事件内 widow.onscroll = function () { /* 卷去的高度 console.log(document.documentElement.scrollTop) console.log(document.body.scrollTop) */ var scrollTop = documentElement.scrollTop || document.body/scrolltop console.log(scrollTop) //卷去宽度 //console.log(document.documentElement.scrollLeft) //console.log(document.body.scrollLeft) var scrollLeft = document.docunmentElement.scrollLeft || document.body.scrollLeft console.log(scrollLeft) }
- 语法:
浏览器滚动
-
浏览器滚动到
- 定位浏览器卷去的尺寸
- 语法:window.scrollTo(参数)
-
参数方式1:传递数字
- window.scrollTo(x,y)
- x:横向滚动条位置
- y:纵向滚动条位置
- 注意:必须传递两个参数,一个会报错
- 注意:只能进行瞬间定位,不能平滑滚动
- window.scrollTo(x,y)
-
参数方式2:传递对象
- window.scrollTo({left:xxx,top,yyy})
- 注意:可以只书写一个方向
- 注意:默认是瞬间定位,如果的需要平滑滚动,设置对象内第三个成员 behavior:“smooth”
//1、把该代码写在button 按钮的点击事件内 btn.onclick = function () { //传递参数方式1:传递数字 //window.scrollTo(0,0) //传递参数方式2:传递对象 //window.scrollTo({left:0,top:0}) //实现平滑滚动 window.scrollTop({ left:0,top:0,behavior:"smooth"}) }
浏览器标签页
-
打开新的标签页
-
语法:window.open(“地址”)
openBtn.onclick = function(){ //开启新的标签题页 window.open("https://www.baidu.com") }
-
-
关闭当前标签页
-
语法:window.close()
closeBtn.onclick = function () { //关闭当前标签页 window.close() }
-
浏览器的地址栏
-
浏览器的地址栏
- 在window下有一个成员叫做 location,是一个对象,记录的就是地址相关的信息
-
href 属性
-
是一个读写的属性
-
读:window.location.href
-
得到:该地址栏
console.log(window.location.href)
-
-
写:window.location.href = “地址”
-
作用:修改当前地址栏地址,跳转页面
btn.onclick = function(){ window.location.href='https://www.jd.com' }
-
-
-
reload 方法
-
语法:window.location.reload()
-
作用:重新加载当前页面(就是刷新)
btn.onclick = fucntion(){ window.loaction.reload() }
-
-
扩展:浏览器的地址栏
-
https://www.cmx.com:443/a/b/c/index.html?a=100&b=200#abc
标题 说明 http(s) 传输协议 www.cmx.com 域名(为了找到了网络世界内的某一个电脑) 443 端口号( 0 ~ 65535 ) /a/b/c/index.html 地址(为了找到指定的文件) ?a=100&b=200 查询字符串(queryString)不影响页面的打开,给当前页面的一些信息
-
浏览器的历史记录
- 在window下有一个成员叫做history,是一个对象,里面记录的都是历史记录相关的操作信息
- 回退
- 语法:window.history.back()
- 作用:回退到上一条历史记录,等价于 ⬅ 按钮
- 前进:
- 语法:window.history.forward()
- 作用:前进到下一条历史记录,等价于 ➡ 按钮
- 跳转
- 语法:window.history.go(参数)
- 正整数:前进
- 0:刷新
- 负整数:回退
- 语法:window.history.go(参数)
浏览器本地存储-Storage
-
浏览器本地存储 - storage
- storage:仓库
- storage 在浏览器分成两种
- localStorage 永久存储
- sessionStorage 会话存储(关闭浏览器页面就消失了)
-
特点:
- 不管你存储的是什么内容,都会变成字符串
- 只能存储字符串类型术数据
- 存储大小:20MB 左右
- 按照域名存储:哪一个域名存储的,哪一个域名使用(本地文件使用一个 file://)
-
localStorage 本地存储
-
设置:window.locatStorage.setItem(key,value)
window.localStorage.setItem('a',JSON.stringify({ name:'jack'})) window.localStorage.setItem('b',200) window.localStorage.setItem("c",300)
-
获取:windoiw.localStorage.getItem(key)
var res = window.localStorage.getItem('a') console.log(res) console.log(typeof res)
-
删除:window.localStorage.removeItem(key)
btn.onclick = function(){ //删除 window.localStorage.removeItem("a") }
-
清除:window.localStorage.clear()
btn.onclick() = function(){ //清除 window.localStorage.clear() }
-
-
sessionStorage 会话存储
-
设置:window.sessionStorage.setItem(key,value)
window.sessionStorage.setItem('a', 100) window.sessionStorage.setItem('b', 200) window.sessionStorage.setItem('c', 300)
-
获取:window.sessionStorage.getItem(key)
var res = window.sessionStorage.getItem(”a) console.log(res)
-
删除:window.sessionStorage.removeItem(key)
brn.onclick = function(){ window.sessionStorage.removeItem('a') }
-
清除:window.sessionStorage.clear()
btn.onclick = function(){ window.sessionStorage.clear() }
-
浏览器的本地存储 -cookie
-
特点:
-
按照域名存储,
-
哪一个域名使用
-
必须把页面服务器打开才能使用
-
-
存储大小
- 4KB 左右
-
存储格式
- 只能是 “key=value;key2=value2;…”
-
存储时效性
- 默认是 会话级别时效(关闭浏览器就会消失)
- 可以手动设置过期时间
-
操作性
- 前端可以操作(JS)
- 后端也可以操作(任何一个语言)
-
请求自动跟随
- 只要cookie 空间内有内容 ,那么当前页面发送的请求是可以自动携带的
-
-
如何在服务器启动页面
- 简单借助 vscode 的插件 来实现
- 下载一个插件叫做 live server
- 将来打开页面的时候,使用 右键单击,选择open with live server
-
设置cookie
-
语法:document.cookie = ‘key=value’
-
注意:一次只能设置一条
document.cookie = 'a=100'
-
-
设置一条带有过期时间的 cookie
-
语法:document.cookie = “key=value;expires=时间对象”
-
说明:
- 当你设置带有过期时间的cookie 的时候
- 你给的时间对象不管是什么时候,都会当做世界标准时间使用
- 例子:
- 你设置的时候是 16 : 34
- cookie 拿到 16 : 34 会当做世界标准时间使用
- 该 cookie 会在世界标准时间 16 : 34 过期,被自动删除
- 世界标准时间的 16 : 34 是北京时间的 00 : 34
-
设置一条 30s 以后过期的 cookie
-
拿到当前时间节点
-
向前调整 8 个小时
-
在向后顺延 30s 就可以了
var time = new Date() var t = time.getTime() - 1000*60*60*8 + 1000 *30 //利用用这个时间戳,再次设置 time 这个时间对象去进行时间节点的定位 time.setTime(t) //设置cookie document.cookie = "a=100;expires="+time //'key=value;expires=’+time
-
-
-
读取cookie
-
语法:document.cookie
-
得到:完整的cookie字符串
var c = document.cookie //console.log(c) var obj = { } c.split(";").forEach(function(item){ var t = item.split("=") obj[t[0]] = t[1] }) console.log(obj)
-
-
作业1:封装函数设置cookie
// 作业1: 封装函数设置 cookie // function setCookie( ... ) {} // // 将来使用的时候 // // 设置一条 a=100 这样的 cookie, 过期时间就是 会话级别过期 // setCookie('a', 100) // // 设置一条 b=200 这样的 cookie, 过期时间就是 30s 以后 // setCookie('b', 200, 30) function setCookie(key, value, seconds) { var time = new Date() var t = time.getTime() - 1000 * 60 * 60 * 8 + 1000 * seconds time.setTime(t) return (document.cookie = `${ key}=${ value};expires=` + time) } var res = setCookie("name", "陈明旭", 20000) var res1 = setCookie("age", 22, 20000) console.log(res) console.log(res1)
-
作业2:封装函数获取cookie
// 作业2: 封装函数获取 cookie // function getCookie( ... ) {} // 将来使用的时候 // var res = getCookie() // res 得到的就是一个对象, 里面包含所有的 cookie 内容 function getCookie() { var c = document.cookie console.log(c) var obj = { } c.split("; ").forEach(function (item) { var t = item.split("=") obj[t[0]] = t[1] }) return obj } var res2 = getCookie() console.log(res2)
浏览器的历史记录
- 在window下有一个成员叫做history,是一个对象,里面记录的都是历史记录相关的操作信息
- 回退
- 语法:window.history.back()
- 作用:回退到上一条历史记录,等价于 ⬅ 按钮
- 前进:
- 语法:window.history.forward()
- 作用:前进到下一条历史记录,等价于 ➡ 按钮
- 跳转
- 语法:window.history.go(参数)
- 正整数:前进
- 0:刷新
- 负整数:回退
- 语法:window.history.go(参数)
浏览器本地存储-Storage
-
浏览器本地存储 - storage
- storage:仓库
- storage 在浏览器分成两种
- localStorage 永久存储
- sessionStorage 会话存储(关闭浏览器页面就消失了)
-
特点:
- 不管你存储的是什么内容,都会变成字符串
- 只能存储字符串类型术数据
- 存储大小:20MB 左右
- 按照域名存储:哪一个域名存储的,哪一个域名使用(本地文件使用一个 file://)
-
localStorage 本地存储
-
设置:window.locatStorage.setItem(key,value)
window.localStorage.setItem('a',JSON.stringify({ name:'jack'})) window.localStorage.setItem('b',200) window.localStorage.setItem("c",300)
-
获取:windoiw.localStorage.getItem(key)
var res = window.localStorage.getItem('a') console.log(res) console.log(typeof res)
-
删除:window.localStorage.removeItem(key)
btn.onclick = function(){ //删除 window.localStorage.removeItem("a") }
-
清除:window.localStorage.clear()
btn.onclick() = function(){ //清除 window.localStorage.clear() }
-
-
sessionStorage 会话存储
-
设置:window.sessionStorage.setItem(key,value)
window.sessionStorage.setItem('a', 100) window.sessionStorage.setItem('b', 200) window.sessionStorage.setItem('c', 300)
-
获取:window.sessionStorage.getItem(key)
var res = window.sessionStorage.getItem(”a) console.log(res)
-
删除:window.sessionStorage.removeItem(key)
brn.onclick = function(){ window.sessionStorage.removeItem('a') }
-
清除:window.sessionStorage.clear()
btn.onclick = function(){ window.sessionStorage.clear() }
-
浏览器的本地存储 -cookie
-
特点:
-
按照域名存储,
-
哪一个域名使用
-
必须把页面服务器打开才能使用
-
-
存储大小
- 4KB 左右
-
存储格式
- 只能是 “key=value;key2=value2;…”
-
存储时效性
- 默认是 会话级别时效(关闭浏览器就会消失)
- 可以手动设置过期时间
-
操作性
- 前端可以操作(JS)
- 后端也可以操作(任何一个语言)
-
请求自动跟随
- 只要cookie 空间内有内容 ,那么当前页面发送的请求是可以自动携带的
-
-
如何在服务器启动页面
- 简单借助 vscode 的插件 来实现
- 下载一个插件叫做 live server
- 将来打开页面的时候,使用 右键单击,选择open with live server
-
设置cookie
-
语法:document.cookie = ‘key=value’
-
注意:一次只能设置一条
document.cookie = 'a=100'
-
-
设置一条带有过期时间的 cookie
-
语法:document.cookie = “key=value;expires=时间对象”
-
说明:
- 当你设置带有过期时间的cookie 的时候
- 你给的时间对象不管是什么时候,都会当做世界标准时间使用
- 例子:
- 你设置的时候是 16 : 34
- cookie 拿到 16 : 34 会当做世界标准时间使用
- 该 cookie 会在世界标准时间 16 : 34 过期,被自动删除
- 世界标准时间的 16 : 34 是北京时间的 00 : 34
-
设置一条 30s 以后过期的 cookie
-
拿到当前时间节点
-
向前调整 8 个小时
-
在向后顺延 30s 就可以了
var time = new Date() var t = time.getTime() - 1000*60*60*8 + 1000 *30 //利用用这个时间戳,再次设置 time 这个时间对象去进行时间节点的定位 time.setTime(t) //设置cookie document.cookie = "a=100;expires="+time //'key=value;expires=’+time
-
-
-
读取cookie
-
语法:document.cookie
-
得到:完整的cookie字符串
var c = document.cookie //console.log(c) var obj = { } c.split(";").forEach(function(item){ var t = item.split("=") obj[t[0]] = t[1] }) console.log(obj)
-
-
作业1:封装函数设置cookie
// 作业1: 封装函数设置 cookie // function setCookie( ... ) {} // // 将来使用的时候 // // 设置一条 a=100 这样的 cookie, 过期时间就是 会话级别过期 // setCookie('a', 100) // // 设置一条 b=200 这样的 cookie, 过期时间就是 30s 以后 // setCookie('b', 200, 30) function setCookie(key, value, seconds) { var time = new Date() var t = time.getTime() - 1000 * 60 * 60 * 8 + 1000 * seconds time.setTime(t) return (document.cookie = `${ key}=${ value};expires=` + time) } var res = setCookie("name", "陈明旭", 20000) var res1 = setCookie("age", 22, 20000) console.log(res) console.log(res1)
-
作业2:封装函数获取cookie
// 作业2: 封装函数获取 cookie // function getCookie( ... ) {} // 将来使用的时候 // var res = getCookie() // res 得到的就是一个对象, 里面包含所有的 cookie 内容 function getCookie() { var c = document.cookie console.log(c) var obj = { } c.split("; ").forEach(function (item) { var t = item.split("=") obj[t[0]] = t[1] }) return obj } var res2 = getCookie() console.log(res2)