菜鸟教程:AngularJS 参考手册 | 菜鸟教程
W3school:JavaScript 参考手册
MDN:JavaScript 参考 - JavaScript | MDN
JS的标准命名为ECMAScript,但实际上JavaScript的含义更大一些。JavaScript包括ECMAScript、DOM(文档对象模型,通过JS操作网页)、BOM(浏览器文档对象模型,通过JS操作浏览器)
JS的出现主要用于处理网页中的前端验证(在浏览器中检查用户输入的内容是否符合一定的规则,如:用户名的长度,密码的长度,邮箱的格式)
ECMA 欧洲计算机联盟
Web APIs 包括 DOM(控制标签,对页面元素进行移动、大小、添加、删除等操作),BOM(操作浏览器,比如页面弹窗、检测窗口宽度、存储数据到浏览器)
点击按钮或超链接时,js代码才会执行
点击超链接
script可以写到标签内部
注意:不要在标签中写代码,会不生效
可查询Unicode编码对照表
断点调试
把 变量、表达式、条件判断 添加至监视表达式,然后刷新,一步一步执行(注意:点两次执行该语句或到下一句才执行)
第1个图标:跳过下一个函数调用,不进入函数内部;
第2个图标:进入下一个函数调用,会一步一步执行;
prompt("请输入你的年龄");
//不仅可以输出文字,还可以解析输出标签
document.wwrite('名字
')
注意:
变量就是一个容器,是内存里的一块空间,用于存储数据(为什么需要变量?)。方便以后使用里面的数据。
let / var / const 都可以声明变量
let name = '比方'
let name = '粉笔'
此写法错误
var a; let b; const c=123;
声明变量 变量名=变量值; 例:var age=18;
声明的同时赋值称为变量的初始化
一个变量被重新赋值后,它原来的值就会被覆盖,变量值将以最后一次赋的值为准。
只需写一个var,多个变量名之间用英文逗号隔开
var name="旗木卡卡西",sex='女',age="30";
JS中可以由自己命名的称为标识符。如,变量名,函数名,属性名
(1)由字母、数字、下划线(-)、美元符号($)组成(注:命名的单词间不能有空格);
(2)不能以数字开头;
(3)不能是关键字、保留字,(注:在有些浏览器中name是有含义的,所以尽量不用name,可以用myName);
(4)严格区分大小写。var age和var Age是两个变量;
(5)遵守驼峰命名法。首字母小写,后面单词的首字母大写(小驼峰),如,myFirstName
1.交换变量
var a=1,b=3;
var t=a; //t为临时变量
var a=b;
var b=t;
console.log(a,b); //a=3,b=1
2.输入并弹出用户名
var a=prompt("请输入你的名字");
alert("欢迎"+a);
根据数据所占空间不同,分成了不同的数据类型。(充分利用存储空间)
简单类型和复杂类型:
JS进行浮点运算可能不精确,因为计算机是二进制
Number.MAX_VALUE 表示最大数值;
Number.MIN_VALUE 表示大于0的最小值;
Infinity 表示正无穷;
-Infinity 表示负无穷;
NaN 是一个特殊的数字,表示not a number;
使用表单、prompt 获取过来的数据默认是字符串类型的
1)用 '' (单引号) / ""(双引号) / ``(反引号) 包裹的都是字符串
2)在JS中字符串需要使用引号(双引号或单引号都可以,但不要混着用)引起来,不加引号会被认为成变量;
3)引号不能嵌套。双引号里不能放双引号,单引号里不能放单引号(就近原则),但双引号里能放单引号,单引号里能放双引号;
\” 表示 双引号“
\’ 表示 单引号 ’
\n 表示 换行 注:要放在引号里使用 '\n' 反引号内不用加引号 \n只能console.log中起作用
\t 表示 Tab键
\b 表示 空格
\\ 表示 一个斜杠 \
\\\\ 表示 两个斜杠 \\
var s="来庄里吧!";
console.log(s.length); /*length=5*/
方法一:加号(+)
只要有字符串和其他类型相拼接,最终的结果是字符串类型(拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字符串)
console.log("河北"+"石家庄"); /* 河北石家庄 */
console.log("SHY"+24); /* SHY24 */
console.log("12"+12); /* 1212 */
console.log("河北"+true); /* 河北true */
字符串和变量的拼接(因为变量可以很方便地修改里面的值)
var name="旗木卡卡西",age="25";
console.log('你好,我叫'+name+',今年'+age+'岁了!')
用户输入并反馈给用户
var age=prompt('请输入您的年龄:');
alert('您今年'+age+'岁啦!');
方法二:模板字符串(反引号与${})
let name="旗木卡卡西",age="25";
document.write(`我是${name},今年${age}了!`)
布尔型有两个值:true(真)和false(假);
布尔型与数字型相加时,true的值为1,false的值为0;
console.log(true+3); //1+3=4
console.log(false+3); //0+3=3
(1)null表示一个为空的对象;
使用typeof检查一个null值时,会返回object;
(2)当声明一个变量,但不赋值时,它的值就是undefined;
使用typeof检查一个undefined时,会返回undefined;
console.log(null+2); //0+2=2
console.log(undefined+3); //NaN
console.log(null+'SHY'); //null+SHY
console.log(undefined+'SHY'); //undefinedSHY
形式:typeof+变量名
注:null值返回的是object;prompt返回的是字符型(string).
var name="旗木卡卡西"; //string
var a=null; //object
var b; //unundefined
document.write(typeof name,a,b);
var age=prompt('请输入您的年龄:');
document.write(typeof age); //string
1)方式一 tostring()方法不会影响到原变量,它会将转换的结果返回,但null和undefined这两个值没有tostring()方法,如果调用他们的方法会报错。
num.toString() | // 数字17转成string类型 let A = (17).toString() // 结果为 17,类型为 string |
num.toString(进制数) | // 17转16进制 let A = (17).toString(16) // 结果为 11,类型为 string |
2)方式二 调用 string(数据) 函数,并将被转换的数据作为参数传递给函数;使用string()函数做强制类型转换时,对null和undefined及其它所有类型都起作用(将null转换为”null” 将undefined转换为” undefined”)。
3)方式三 隐式转换的形式:变量+' ' 如,alert(unm+' ');
1)parseInt()可以将一个以数字开头的字符串中的有效的整数(遇到出数字以外的内容就结束)内容取出来
如:123.45px经ParseInt()转换成123
12a3.45px经ParseInt()转换成12
123px456经ParseInt()转换成123
abc12.35经ParseInt()转换成NaN
true 经ParseInt()转换成 NaN
false 经ParseInt()转换成 NaN
'null' 经ParseInt()转换成 NaN
null 经ParseInt()转换成 0
2)parseFloat()可以获得以数字开头的非纯数字字符串中有效的小数
如:123.456px经ParseInt()转换成123.456
123.456.789px经ParseInt()转换成123.456
3)number()函数
4)隐式转换(- * /)
+数据 +作为正号,其他数据类型可以转为数字类型(input和prompt输入的都是字符串类型)
let A = +prompt('输入工资') // A为数字类型
+的作用:连接符、运算符、正号
将字符型12转换成数值型12,再进行运算
console.log('12'-0) //12
console.log('123'-'120') //3
console.log('12'*1) //12
console.log('12'/1) //12
5)三个案例
1.计算年龄案例
var year=prompt('请输入您的出生年份:');
var nowyear=2021;
var age=nowyear-year; //year为字符串型,这里用的减法,有隐式转换
alert('今年您'+age+'岁啦!');
2.简单加法器案例
var num1=prompt('请输入第一个值:');
var num2=prompt('请输入第二个值:');
var sum=Number(num1)+Number(num2);
var minus=num1-num2;
var mul=num1*num2;
var into=num1/num2;
alert('两个值之和为:'+sum);
alert('两个值相减为:'+minus);
alert('两个值相乘为:'+mul);
alert('两个值相除为:'+into);
3.依次询问并获取用户的姓名、年龄、性别,并打印用户信息(\n要放在引号里)
var myname=prompt('姓名'),age=prompt('年龄'),sex=prompt('性别');
alert('姓名:'+myname+'\n'+'年龄:'+age+'\n'+'性别:'+sex);
代表空、否定的值( ' '、0、NaN、null、undefined)会被转换为false
!!'23' 转成布尔值
注:
(1)浮点数值得最高精度是17位小数,但在进行算数计算时其精确度远远不如整数。所以,不要直接判断两个浮点数是否相等(var a=0.1+0.2;console.log(a==0.3);)
(2)如果对两个字符串进行加法运算,则会做拼串(连接符)。即,任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串
1+2+”3”=33
“1”+2+3=123
100-“2”=98
2*“8“=16
2*null=0
// 小数与大数的余数为小数本身
2 % 7 = 2
(10-2) % 12 =8
2 % 7 - 9 / 3 = -1
任何值n取余,值为 0,1,2,... n-1
例:0,1,2,3,4,5,6 与3的余数
0 1 2 0 1 2 0 0-2
注:
++a —> a=a+1 a++ —> a=a+1
++a,--a (在使用a之前,先使a的值加/减1)
a++,a-- (在使用a之后,使a的值加/减1)
var num1=10; console.log(++num1 +10); /*21*/
var num2=10; console.log(num2++ +10); /*20*/
// 后置自增(减)到了运算符的另一边完成自增(减)
var d=20; var result=d++ + ++d + d ; /*20+22+22=64*/
let a=3; let result=++a + a++ + a++ + ++a /* 4+4+5+7=20 */
1.==判等号(判断两边的值是否相等)
console.log(18=='18'); /* true */
console.log(1 == 'pink') /* false 值根本不相等 */
2.===全等(两侧的值和数据类型完全一致才可以)
console.log(18==='18') /*false*/
console.log(1 == 'pink') /*false*/
3.!== 不全等(两边数据类型和值,只要有一个不等,就是true)
console.log(18!==18) /*false*/
console.log(18!=='18') /*true,类型不等*/
console.log(25!==18) /*true,值不等*/
4. > < <= >= 不同类型的比较会默认转换成number类型再比较(把字符串型的数据转换成数字型)
(1)比较运算符的返回值为true、false
(2)任何值和NaN做任何比较都是false
10<="hello" //false true>false //true NaN===NaN //false
(3)不要做小数运算,会有精度问题
0.1+0.2!=0.3
(0.1*10+0.2*10)/10=0.3 因为整数没有精度问题
(4)两个字符串比较:(比较字符对应的ASCII码)
与(&&) 两个都为真,返回值为真(true);其中一个为假,返回值就为假(false);
或(||) 其中一个为真,返回值就为真(true);两个都为假,返回值才为假(false);
非(!) 取反,真为假,假为真;
短路运算原理:当有多个表达式(非布尔进行与或运算)时,左边的表达式可以确定结果时(与&&遇假确定结果,或||遇真确定结果),就不再继续运算右边的表达式的值。
总结:与(&&)返回第一个为false的值;或(||)返回第一个为真的值。
1)逻辑与
语法:表达式1 && 表达式2
如果第一个表达式的值为true,则返回表达式2;如果两个值都为true,则返回后边的;
如果第一个表达式的值为false,则返回表达式1;如果两个值都为false,则返回前边的;
注意:返回的值不是true/false,因为与、或、非没有能力将两侧的值转为true、false,只是判断值为真还是假
console.log(123 && 456); /*456*/
console.log(123 && 456 && 1+2); /*3*/
//左边如果是 0 '' undefin null NaN 则返回自身
console.log(0 && 456); /*0*/
console.log(null && 456); /*null*/
console.log(0 && 456 && 1+2); /*0*/
2)逻辑或
语法:表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1;
如果第一个表达式的值为假,则返回表达式2.
console.log(123 || 456); /*123*/
console.log(0 || 456 || 1+2); /*456*/
例:
var num=0;
console.log(123 || num++); /*中断运算*/
console.log(num); /*0*/
例:num += 3 —> num=num+3
顺序结构是程序中最简单、最基本的流程控制,程序会按照代码的先后顺序,依次执行。
1.if-else 双分支
if (条件)
{语句1;}
else
{语句2;}
2.if-else if 多分支(检查多重条件,可以处理范围)
if (条件1)
{语句1;}
else if (条件2)
{语句2;}
else if (条件3)
{语句3;}
else
{语句4;}
判断是否能进入网吧
var age=+prompt("请输入您的年龄:");
if (age>=18) {
alert('允许进入网吧!');
} else{
alert('抱歉,您还未成年!');
}
判断闰平年(能被4整除且不能整除100的年份为闰年或者能够被400整除的就是闰年)
var year=+prompt("请输入年份:");
if (year%4==0&&year%100!=0||year%400==0) {
alert(`${year}为闰年`);
} else{
alert(`${year}为平年`);
}
条件表达式 ?表达式1 :表达式2;
如果条件表达式为真,则返回表达式1;如果条件表达式为假,则返回表达式2。(简化版的if-else,一般用于赋值,比如最大值比较,将最大值赋给变量)
补0操作,可用于倒计时(小于10的数补零,大于10的数不补零)
方法一:
var num=prompt("请输入一个数字:");
num<10 ? alert('0'+num+' 补零') : alert(num+' 不补零');
方法二
var num=prompt("请输入一个数字:");
var result= num<10 ? '0'+num+' 补零' : num+' 不补零';
alert (result);
一般用于等值判断,不适合于区间判断
switch (表达式/变量){
case 值1:语句1;
break; //break 跳出
case 值2:语句2;
break;
...
default:
break;
}
注:
1)case后面必须是一个整数,或是结果为整数的表达式,但不能包含任何变量
2)若某一条case后没有紧跟的语句,则不用带分号和break
3)表达式/变量的值和case里的值匹配时,得是全等关系(值和数据类型都得相同)
4)如果当前的case里没有break,则不会退出,会继续执行下一个case
5)若没有default,并且和任何case值不匹配时,则跳出switch,什么都不执行
1. 查询水果价格
var fruit=prompt("请输入一种水果:");
switch (fruit){
case '苹果':alert("苹果 0.8/斤"); //水果名称要加引号,因为要全等匹配
break;
case '香蕉':alert("香蕉 1.5/斤");
break;
case '草莓':alert("草莓 2/斤");
break;
default:alert("无此种水果");
break;
}
2. 用户输入2个数字
在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句。
循环的目的:重复的执行某些代码。
for (初始化变量 ; 条件表达式 ; 操作表达式) {循环体}
for (var i=1,j=0 ; i<=10 ; i=i+2) {循环体}
(1)注意是var,不是int
(2)当有多个初始化变量时,要用“,”隔开
(3)for循环的变量(int i)是个局部变量,只在for循环体里有效
for循环可以嵌套if语句
for (var i=1;i<=20;i++) {
if (i==1){
console.log('1岁了,出生年!');
}
else if (i==18) {
console.log('18岁,成年了!');
}
else {console.log('今年'+i+'岁了');}
}
1-100的总和、平均值、奇数、偶数、能被3整除的数字的和
var sum=0,odd=0,even=0,result=0;
for (var i=1;i<=100;i++) {
sum+=i; //总和
if (i%2!=0) { //奇数
odd+=i;
}
else {even+=i;} //偶数
if (i%3==0){ //能被3整除的
result+=i;
}
}
document.write('和为:'+sum,'平均数为:'+sum/100,'奇数'+odd,'偶数'+even,'能被3整除的数字的和'+result);
输入班级人数并计算出总成绩和平均成绩
var num=prompt ('请输入班级人数:');
var sum=0;
for (var i=1;i<=num;i++) {
var sorce=prompt ('请输入第'+i+'个人的成绩:')
sum+=parseFloat(sorce); //prompt取过来的是字符型,需要转换成数字型
}
alert('班级总成绩为:'+sum);
alert('班级平均成绩为:'+sum/num)
for循环双层嵌套
for(外边循环变量的起始值;循环条件;变化值){
for(里边循环变量的起始值;循环条件;变化值){
}
}
图一:一行打印5颗♥ 重点:转换为字符串就可以在一行上打印出
var str='';
for(i=1;i<=5;i++){
str=str+'♥';
}
console.log(str);
图二:五行五列
var str='';
for(i=1;i<=5;i++){ //外面for是列,控制里层for要循环多少次
for(j=1;j<=5;j++){ //里面for是行,控制每一行的个数
str=str+'♥';
}
str=str+'\n';
}
document.write(str);
图三:倒三角
var str='';
for(i=1;i<=10;i++){
for(j=i;j<=10;j++){ //(j=10;j>=1;j--)错误,因为这样每次循环j=10,所以最后结果的每行都是10个
str=str+'♥';
}
str=str+'\n';
}
console.log(str);
正三角
var str='';
for(i=1;i<=10;i++){
for(j=1;j<=i;j++){
str+='♥';
}
str+='\n';
}
console.log(str);
九九乘法表
var str='';
for(i=1;i<=9;i++){
for(j=1;j<=i;j++){ //每一行公式的个数正好和行数一致,所以 j<=i
str+=j+'*'+i+'='+j*i+'\t'; //j*i=行*列
}
str+='\n';
}
console.log(str);
打印在网页中(\n只是输出一个空格;
在JS里也是换行)
for(i=1;i<=9;i++){
for(j=1;j<=i;j++){
document.write(j+'*'+i+'='+j*i+'\t');
}
document.write('
');
}
1.while (先判断 再执行)
var 声明变量并初始化;
while(循环条件)
{循环体;}
2.do-while (先执行 再判断)
do {循环体;}
while (循环条件);
循环案例
1.打印人的一生,从1岁到100岁
(1)while
var age=1;
while(age<=100)
{document.write('今年'+age+'岁了!'+'
');
age++;}
(2)do-while
var age=1;
do{
document.write('今年'+age+'岁了!'+'
');
age++;
}while(age<=100);
2.计算1-100之间所有整数和
(1)while
var num=1,sum=0;
while(num<=100){
sum+=num;
num++;
}
document.write(sum);
(2)do-while
var num=1,sum=0;
do{
sum+=num;
num++;
}while(num<=100);
document.write(sum);
3.弹出一个提示框'love?',如果输入'yes'就结束,否则就一直询问
(1)while
var answer=prompt('love?');
while(answer!='yes'){
answer=prompt('love?'); //不能只写prompt('love?'); 要给它一个变量保留它的值,才能返回判断,否则会陷入死循环
}
(2)do-while
var answer=prompt('love?');
do{
answer=prompt('love?');
}while(answer!='yes');
(3)开关法(不确定循环的次数)
循环次数已知的,用for循环;循环次数未知的用while循环;
用来计数,跟数字有关,常用for;
while和do-while可以做更复杂的判断条件,比for循环更灵活。
break | 跳出当前整个循环,只能跳出一层循环 |
---|---|
continue | 结束本次循环,判断循环条件,如果成立,则进入下一次循环,否则退出整个循环 |
goto | 跳出多层循环 |
1. 求1-100之间,除了能被7整除之外的整数和
var sum=0;
for(var i=1;i<=100;i++){
if(i%7==0){
continue;
}
sum+=i;
}
document.write(sum);
2. 打印1-10的奇数
// 思路:跳过偶数,打印奇数
for(let i=1;i<=10;i++){
if(i%2===0){
continue
}
console.log(i)
}
3. 求1-100前3个能被7整除的数的和
let sum = 0
let count = 0 //计数器
for (let num = 1; num <= 100; num++) {
if (num % 7 === 0) {
count++
// 当次数为4时就跳出循环
if (count === 4) {
break
}
sum += num
// 当计数器写在和的下面时,到3次时就要跳出循环
/* if (count === 3) {
break
} */
}
}
console.log(sum)
方法一:
// 开关法循环,在循环外边定义一个变量为true,进入循环体里边去,想要结束循环,变量在循环里=false
let flag = true,
money = 0
while (flag) {
let num = +prompt(`请选择您的操作:
1. 存款
2. 取款
3. 查看余额
4. 退出`)
switch (num) {
case 1:
let add = +prompt('请输入存款金额:')
money += add
break
case 2:
let get = +prompt('请输入存款金额:')
money -= get
break
case 3:
alert(`余额为${money}`)
break
case 4:
flag = false
break
default: alert('请输入正确序号')
}
}
方法二:
alert('欢迎登入!');
var money=0;
for (var i=1;i>=1;i++){
var num=prompt('请输入您要的操作:'+'\n'+'1.存钱'+'\n'+'2.取钱'+'\n'+'3.查询余额'+'\n'+'4.退出')
//一开始的输入框要写在for循环内,才能每次返回到开始的界面
if (num=='1') {
money1=prompt('请输入存的钱数:');
money+=parseFloat(money1);
alert('现在余额为:'+parseFloat(money));
}
else if (num=='2') {
cut=prompt('请输入取的钱数:');
cut=parseFloat(cut);
if (cut<=money){
money=parseFloat(money-cut);
alert('现在余额为:'+money);
}
else {alert('余额不足!');}
}
else if (num=='3') {
alert('现在余额为:'+parseFloat(money));
}
else if (num=='4') {
alert('现在正在退出!');
break;
}
else {alert('请按要求输入!');}
}
// 计算数组[2,6,18,15,40] 中能被3整除的偶数的个数
let arr = [2, 6, 18, 15, 40]
let count = 0
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 3 === 0 && arr[i] % 2 === 0) {
count++
}
}
console.log(count)
数组是指一组数据的集合,其中的每个数据被称作数组元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的方式。
数组中可以放任意类型的数据;数组元素之间要用','逗号隔开。
var 数组名=[ ];
var a=[20,'城南',true];
var 数组名=new Array( ); 注意A要大写
var a = new Array(1,'短信',true);
数组名[元素的索引号]
a[2] 获取a数组中索引号为2的元素。如果没有这个数组元素,输出的结果会是 undefined
索引(下标):用来访问数组元素的序号(数组索引号从0开始)
遍历:把数组中的每个元素从头到尾都访问一次。
?结果有问题 不能用name作为数组名,因为name是关键词
?结果无引号 alert无引号,console.log控制~台有引号
var forename=['刘备','关羽','张飞','马超'];
for(var i=0;i<4;i++){ //i从0开始;i<=元素个数(forename.length)
console.log(forename[i]);
}
数组名.length
a.length //数组a中元素的个数,length为变量属性名
(1)修改数组索引,添加/更改数组元素
查 | 数组名[索引号] | 用来判断数组中是否包含某个对象或值 indexOf或findIndex() |
---|---|---|
改 | 数组名[索引号]=要改成的值 | |
增 | 数组名.push(数据1,数据2,...数据n) | 新增加的数组元素在数组的末尾 |
console.log(数组名.push(数据1,数据2,...数据n)) | 打印此语句,返回新数组的长度 | |
数组名.unshift(数据1,数据2,...数据n) | 新增加的数组元素在数组的前边 | |
console.log(数组名.unshift(数据1,数据2,...数据n)) | 打印此语句,返回新数组的长度 | |
删 | 数组名.pop( ) | 删除数组的最后一个元素 |
数组名.shift( ) | 删除数组的第一个元素 | |
console.log(数组名.pop( )) | 返回被删除的元素 | |
console.log(数组名.shift( )) | ||
数组名.splice(开始删除元素的索引值,删除的数量,新增数据1,新增数据2) | 批量删除(抽奖、购物车) 返回被删除的元素 |
|
数组名.filter( ) // 过滤 |
var str=['红','绿','蓝','白'];
str[0]='黄'; //更改 结果:黄,绿,蓝,白
str[5]='黑'; //添加 结果:红,绿,蓝,白,黑
str.push=[1,2] //添加 结果:红,绿,蓝,白,1,2
console.log(str.push=[1,2]) // 结果:6(长度)
str.unshift=[A,B,C] //添加 结果:A,B,C,红,绿,蓝,白
console.log(str.unshift=[A,B,C]) // 结果:7(长度)
str.pop() // 删除 结果:'红','绿','蓝'
console.log(str.pop()) // 结果:'白'
str.shift() // 删除 结果:'绿','蓝','白'
console.log(str.shift()) // 结果:'红'
str.splice(1,2) // 批量删除 结果:'红','白'
str.splice(1) // 批量删除 结果:'红' (将起使元素后面的元素都删除)
str.splice(1,1) // 批量删除 结果:'红','蓝','白' (只删除起使元素)
str='赋值没加索引'; //结果:赋值没加索引
注意:不能直接给数组名赋值,否则会覆盖掉以前的数据
(2)修改length,实现数组扩容
数组名.length=想要扩到的长度;
a.length=7;
数组的方法 | 作用 | 举例 |
---|---|---|
reverse |
翻转数组顺序 |
数组名.reverse() |
indexOf | 在数组中查找某项首次出现的索引位置,找到返回索引值,找不到返回 -1 可用来判断数组中是否包含某个对象或值 |
数组名.indexOf('数组中的某一项元素') |
lastIndexOf | 在数组中查找某项最后出现的索引位置,找到返回索引值,找不到返回 -1 | 数组名.lastIndexOf('数组中的某一项元素') |
join |
拼接数组的每个元素成为字符串 |
数组名.join('拼接的符号或为空') |
concat | 拼接数组成为新数组 | a.concat(b, c, 'aa', 'bb', 'cc') 把数组b/c及'aa'等拼接到数组a后面 |
数组的静态方法 | 作用 | 举例 |
---|---|---|
Array.isArray(数组名) | 判断是否是数组类型,返回布尔值 | let arr=[1,2,3] Array.isArray(arr) |
Array.from(伪数组名) | 把伪数组转换为真数组 注意:转真数组时,伪数组必须有length属性,length可以比伪数组元素的数量多(undefined)或少(有几个就显示几个) |
let as = { 0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', length: 6 } Array.from(as) |
遍历数组的方法:7种
每个方法都有3个形参:
item 第一个参数,代表当前项(arr[i])
index 第二个参数,代表当前项的索引值(i)
o 第三个参数,代表当前数组(arr)
let arr = [3, 2, 6, 7, 9, 4] // 全局数组变量
1. forEach:遍历数组
arr.forEach(function (item, index, o) { console.log(item) })
arr.forEach(item => console.log(item)) // 箭头函数
2. filter:过滤 筛选出满足条件的值放到数组中返回,可用于删除
let re = arr.filter(function (item) {
return item % 2 === 0 // 返回偶数
})
console.log(re) // 结果:[2,6,4]
3. map:依次让每个元素执行一遍回调,把结果全部放到数组中返回
let re = arr.map(function (item) {
return item * item
})
console.log(re) // 结果:[9,4,36,49,81,16]
4. find:遍历查找满足条件的首个元素,并返回这个元素
let re = arr.find(function (item) {
return item >5
})
console.log(re) // 结果:6
5. findIndex:遍历查找满足条件的首个元素,并返回这个元素的索引值
可用来判断数组中是否包含某个对象或值
let re = arr.findIndex(function (item) {
return item > 5 或 item.name=='张三'
大于5的值 数组中name为张三的对象
})
console.log(re) // 结果:2
6. some:遍历查找是否有满足条件的值,有一个就立刻返回true,没有则返回false
let re = arr.some(function (item, index) {
console.log(index) // 输出:0 1 2 说明有一个满足条件就立刻返回
return item > 5
})
console.log(re) // 结果:true
7. every:遍历查找满足条件的值,都满足返回true,有一个不满足就返回false
let re = arr.every(function (item, index) {
console.log(index) // 输出:0 1 说明有一个不满足条件就立刻返回false
return item > 2
})
console.log(re) // 结果:false
将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组
方法一:
var num=[2,0,6,1,77,0,52,0,25,7];
var num1=[];
var j=0;
for(var i=0;i=10){
num1[j]=num[i];
j++;
}
}
alert(num1);
方法二:(不用申请新变量j)
var num=[2,0,6,1,77,0,52,0,25,7];
var num1=[]; //空数组length为0
for(var i=0;i<10;i++){
if(num[i]>=10){
num1[num1.length]=num[i]; //length自动检测数组的长度
}
}
alert(num1);
方法三:
let arr=[2,0,6,1,77,0,52,0,25,7]
// 思路:遍历数组,筛选出>=10的元素,用if追加到新数组
let newArr=[]
for(let i=0;i<=arr.length;i++){
if(arr[i]>=10){
newArr.push(arr[i])
}
}
console.log(newArr)
1. 将[2,0,6,1,77,0,52,0,25,7]中的0去掉后,形成一个不包含0的新数组
var num=[2,0,6,1,77,0,52,0,25,7];
var num1=[];
for(i=0;i
2. 需求:将不重复的元素放入新数组
思路:依次获取数组arr的值,去newArr里查看是否有这个元素,如果没有这个值就添加
let arr = ['a', 1, 2, 'b', 'a', 'c', 'd', 1, 'a', 3, 2]
let newArr = []
for (let i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
console.log(newArr)
将数组[1,2,3,4,5]的内容反过来存放,输出:[5,4,3,2,1]
方法一:
var num=[1,2,3,4,5];
var num1=[];
for(var i=num.length-1;i>=0;i--){ *不同处
num1[num1.length]=num[i]; *
}
alert(num1);
方法二:
var num=[1,2,3,4,5];
var num1=[];
for(var i=0;i
冒泡排序:把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。
冒泡排序一次比较两个元素,如果它们的顺序错误就把它们交换过来,否则不交换。
var num=[1,2,3,4,5]; //可以是任意数组
for(var i=0;i<=num.length-1;i++){ //外层循环总共的趟数(元素个数-1)
for(var j=0;j<=num.length-1-i;j++){ //内层循环每趟比较的次数(元素个数-1-趟数)
if(num[j]
1.返回数组的和、平均值及最大值
var num=[2,6,1,7,4];
var sum=0;
var max=num[0];
for(i=0;i
函数与循环的区别:循环是一次把所有次数执行完,不方便控制执行的位置;函数时需要的时候就调用一次。
函数就是封装了一段可以被重复执行调用的代码块(封装了一定功能),可进行复用。
封装:把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。
书写格式 | 例子 | ||
---|---|---|---|
声明函数 | function | function 函数名() { 函数体代码; } 函数名(); |
function getsum(num1 ) { for(i=0;i } getsum(20); //求1~20的和 |
调用函数 | 函数名(); | ||
注:声明函数本身并不会执行函数,只有调用函数时才会执行函数体代码(即,两者相互配合使用) |
函数名的命名和变量相同,一般以动词为前缀
所在位置 | 说明 | 关系 | |
---|---|---|---|
形参 | function 函数名(形参1,形参2) { 函数体代码; } 函数名(实参1,实参2); |
在声明函数的小括号里面是形参 函数定义的时候传递的参数(形式上的参数) |
1.实参把值传递给形参;形参是接受实参的 2.函数的参数可以有多个(多个参数用逗号隔开),也可以没有 3.开发中尽量保持形参和实参个数一致 4.实参可以是任意的数据类型,数组/变量 |
实参 | 在调用函数的小括号里面是实参 函数调用的时候传递的参数(实际的参数) |
//形参如果不被赋值,就是undefined
function getSum(num1, num2) {
// 利用逻辑中断,将输入的非法值转化成0,使之能顺利进行计算
//或运算找true
num1 = num1 || 0
num2 = num2 || 0
console.log(num1 + num2)
}
//多余的实参(3,5)不会传入函数
getSum(2, NaN, 3, 5) //结果:2
作用:把处理结果返回给调用的函数,可在函数外使用
关键词:return
语法:return 数据
return [num1, num2] (返回多个值时,保存到数组里,再返回给函数调用)
function getSum(num1, num2) {
// 将值返回给调用的函数
return num1 + num2
//此语句不会执行,因为return会立即结束当前函数
document.write('123')
}
console.log(getSum(2, 5)+10)
或
let sum=getSum(2, 5)
console.log(sum);
注意:
作用域分类 | 说明 | 注意 |
---|---|---|
全局作用域 | 函数外部或者整个script 有效 | 如果函数内部或者块级作用域内部,不声明直接赋值使用的变量,是全局变量 |
局部作用域 | 函数内部有效,也称为函数作用域 | 函数的形参可以当做局部变量; 为什么在函数内部声明的变量只能在函数内部被访问,外部无法直接访问 : 执行函数时会开拓出一块区域存放局部变量,执行完就销毁了,所以外部无法直接访问 |
块级作用域 | { } 内有效,包括,if语 句和for语句里面的{ }等 |
变量分类 | 说明 | |
---|---|---|
全局变量 | 函数外部let 的变量 | 全局变量在任何区域都可以访问和修改 |
局部变量 | 函数内部let的变量 | 局部变量只能在当前函数内部访问和修改 |
块级变量 | {} 内部的let变量 | let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问 |
let a = 1 // 全局变量
function fn() {
let b = 2 // 局部变量
if (true) {
let c = 3 // 块级变量
}
}
fn()
作用域链,由作用域串联起来的链状结构(就近查找,如果没有,去上一级)
怎么看一个区域是否有变量:是否有var / let / cost 关键词,否则是使用变量。
作用:提供查找变量的机制。
定义:闭包是一个作用域有权访问另外一个(上级)作用域的变量;
判断是否产生闭包:断点调试出现closure;
作用:可以把一个变量使用范围延伸(局部变量在外边也能用)
闭包本质仍是函数,只不是从函数内部返回的;
闭包能够创建外部可访问的隔离作用域,避免全局变量污染;
过度使用闭包可能造成内存泄漏;
注:回调函数也能访问函数内部的局部变量。
let num = 123;
function f1 () {
let n = 666;
return function () {console.log(n);} // 这个函数是闭包函数
}
let re = f1(); // 返回的是一个函数 结果:function () {console.log(n);}
re(); // 调用返回的这个函数 结果:666
闭包的作用:避免变量污染
let uname='阿飞'
function fn(){
let uname='小狸'
return function(){
console.log(uname)
}
}
fn()() // 实现闭包,局部变量在外面也能用
名次 | 说明 |
---|---|
预解析 | 代码在执行之前先要解析一边,预解析分为 变量提升 和 函数提升。 |
变量提升 | 带有声明的变量,把声明变量的语法提升到当前作用域最前边(注意:只声明不赋值) |
函数提升 | 带有声明的函数,把声明函数的语法提升到当前作用域最前边(注意:只声明不调用) |
注意点:
undefined
console.log(a) // 函数a
function a() {
console.log('aa')
}
var a = 1
console.log(a) // 1
let
声明的变量不存在变量提升(报的错应该是:变量未定义),推荐使用 let
【也有人认为具有提升但是不赋值不能使用(因为报的错是:初始化之前不能使用)】var a=b=c=9
等于
var a=9
b=9 b / c 没有关键词,为全局变量
c=9
将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
let 变量名 = function () {
匿名函数内的代码
}
变量名() // 调用函数
例:
let fn = function () {
console.log(111)
}
fn()
函数也是一种数据
写法一:
;(function () {
console.log(111)
})()
写法二:
;(function () {
console.log(111)
}())
语法:
()
{}
,并自动做为返回值被返回举例:
// 具名函数
function fn() { }
// 箭头函数:相当于具名函数
let fn = () => { 代码块 }
fn()
// 1. 1个形参省略()
// 2. 1句代码块省略{ }
let fn = n => n * n
fn(3) // 9
// 3. 定时器中的箭头函数
setInterval(() => { }, 1000)
setInterval(function () { }, 1000)
注意:
arguments
,只能使用 ...
动态获取实参let obj = {
uname: 'SHY',
age: 18,
school: function () {
console.log(this) // this指的是obj
window.setInterval(() => {console.log(this)}, 1000)} // this指的是obj,不是window
}
undefined;
// 设置参数默认值
function sayHi(name="小明", age=18) { }
sayHi( undefined, 20); // undefined是用来给name占位的
name age
函数的返回值arguments的使用函数的两种声明方式
//取实参中的最大值
//方法一:用arguments函数返回值
function getMax() {
let max = arguments[0]
for (let i = 0; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i]
}
}
return max
}
let num = getMax(5, 30, 12, 50, 25)
console.log(`实参中的最大值是${num}`)
//方法二:老方法,将实参装入数组中
function getMax(a,b,c,d,e) {
let arr = [a,b,c,d,e]
let max=arr[0]
for (let i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
}
return max
}
let num = getMax(5, 30, 12, 50, 25)
console.log(`实参中的最大值是${num}`)
...
是语法符号,置于最末函数形参之前,用于获取多余的实参;...
获取的剩余实参;arguments;
// ...将实参以数组形式存入num中
function log(...num) {
let sum = 0
for (let i = 0; i < num.length; i++) {
sum += num[i]
}
console.log(sum);
}
log(1, 2, 3, 4, 5, 6, 7, 8, 9)
当一个函数A给另外一个函数B当做参数的时候,A函数就是回调函数,B函数就是高阶函数。
函数也是一种数据类型。
1. fun函数是高阶函数,给fun当参数的匿名函数是回调函数
function fun ( n ) {n();}
fun( function () {console.log('aa');} );
2. 事件:
document.addEventLisntener('click', function () { });
回调函数
3. 定时器
setInterval( function () { }, 1000 );
高阶函数 回调函数
利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
let num = +prompt('请输入一个数字,计算1到这个数的阶乘:')
function getN() {
if (num === 1) {
return 1
}
else if (num > 0) {
return num * getN(num - 1)
}
}
alert(`阶乘为${getN()}`)
getN()
环境对象指的是函数内部特殊的变量 this
this指向调用者
1.利用函数计算1-100之间的累加值
function getsum(num) {
var sum=0;
for (i=0;i<=num;i++) {
sum+=i;
}
alert("累加和为:"+sum);
}
getsum(100);
2.用函数求任意两个数之间的和
function getsum(start,end) {
var sum=0;
for (i=start;i<=end;i++) {
sum+=i;
}
alert(start+"与"+end"之间的累加和为:"+sum);
}
/*getsum(start,end); */
getsum(2,10); /*求的是2~10之间的累计和*/
3.求2个数的和
// 方法一:将实参传入函数
function getSum(num1, num2) {
alert(num1 + num2)
}
getSum(2, 3)
getSum(24, 56)
// 方法二:之前的写法,然后封装
function getSum1() {
let num1 = +prompt('输入第一个数')
let num2 = +prompt('输入第二个数')
alert(num1+num2)
}
getSum1()
4.求学生总分
// 求学生总分
function getSum(arr) {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
console.log(sum)
}
// 实参可以是任意的数据类型
getSum([10, 20, 30])
let shy = [20, 30, 40, 100, 50]
getSum(shy)
4-1.求一个数组最大值和最小值
// 求一个数组最大值和最小值
function getNum(arr) {
// 假设第一项为最大值/最小值
let max = min = arr[0]
// 因max = arr[0],所以 i = 1 可减少一次循环
for (let i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
if (min > arr[i]) {
min = arr[i]
}
}
// 返回多个值时,保存到数组里,再返回给函数调用
return [max, min]
}
let res= getNum([20, 50, 30, 10, 40, 100])
console.log(`该数组的最大值为${res[0]},最小值为${res[1]}`)
4-2.求一个数组最大值和最小值的变种
// 求一个数组最大值和最小值
// 函数调用的时候,如果第二个参数为true,返回最大值;如果没有第二个参数,返回最小值
function getNum(arr,flag) {
let max = min = arr[0]
for (let i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
if (min > arr[i]) {
min = arr[i]
}
}
if(flag){
return max
}
else{return min}
}
let res= getNum([20, 50, 30, 10, 40, 100],true)
let res1= getNum([20, 50, 30, 10, 40, 100])
console.log(res)
console.log(res1)
5.求两个数的最大值
// 求两个数的最大值
// 用户输入两个值,比较大小,封装函数,将大的值返回到函数外边,在页面中打印出来
function getNum(num1, num2) {
num1 = +prompt('请输入第一个数值:')
num2 = +prompt('请输入第二个数值:')
return num1 > num2 ? num1 : num2
三元表达式 或 if表达式
if (num1 > num2) {
return `最大值为${num1}`
}
else if (num1 < num2) {
return `最大值为${num2}`
}
else {
return `两值相等`
}
}
alert(getNum())
6.时间转换 (用户输入秒数,可以自动转换为天时分秒)
// 用户输入秒数,可以自动转换为天时分秒
let num = +prompt('请输入要转换的秒数:')
function getTime(time) {
// 天时分秒的转换,只取整数
// 任何值n取余,值为 0,1,2,... n-1
let day = parseInt(num / 60 / 60 / 24)
let hour = parseInt(num / 60 / 60 % 24) // 1天 0-23小时
let min = parseInt(num / 60 % 60) // 1小时 0-59分钟
let sec = parseInt(num % 60) // 1分钟 0-59秒
// 三元表达式补0操作
day = day <= 9 ? '0' + day : day
hour = hour <= 9 ? '0' + hour : hour
min = min <= 9 ? '0' + min : min
sec = sec <= 9 ? '0' + sec : sec
// 函数返回值,一次返回多个数据,用数组
return [day, hour, min, sec]
}
let time = getTime(num) // 调用函数,实参也可以是变量
document.write(`${num}秒被转换成${time[0]}天${time[1]}时${time[2]}分${time[3]}秒`)
let 对象名 = { //对象声明
属性名: 属性值,
方法名: 匿名函数
}
let Person = {
uname:'大黄',
sayHi:function() { console.log('sayHi方法') }, // 方法的函数内可以传参数
'play ball': function () { } //方法名也可加引号,方法之间也用逗号隔开
}
属性访问的2种方法 获取对象里的属性值
(1)对象名.属性名 访问固定属性
console.log(person.my - name) // 不生效
console.log(person.age)
(2)对象名['属性名'] 访问动态属性
console.log(person['my-name'])
console.log(person['sex'])
方法访问的2种方法 调用对象里的方法
(1)对象名.方法名()
person.sing(123) // 可以传参
person.'play ball'() // 错误,多个单词的方法名必须用[]
(2)对象名['方法名']()
person['sing']()
person['play ball']()
注意:
[] 里面的属性名一定加引号;
当属性为动态时用 []
增删改都是基于查的语法之上的。
1. 改(重新赋值) 在对象外操作
(1)对象名.属性名=属性值
person.age = 99
console.log(person.age)
(2)对象名['属性名']=属性值
person['my-name'] = '明明'
console.log(person['my-name'])
(3)对象名.方法名 = 匿名函数 定义时带引号的方法名用此不生效
person.sing = function () {
console.log('sing改1')
}
person.sing()
(4)对象名['方法名']=匿名函数
person['sing'] = function () {
console.log('sing改2')
}
person.sing()
person['play ball'] = function () {
console.log('play ball改2')
}
person['play ball']()
2. 增
(1)对象名.新属性名 = 新属性值
对象名.新方法名 = 新匿名函数
person.school = 'sjzxy'
person.drink = function () {
console.log('喝mink')
}
(2)对象名['新属性名'] = 新属性值
对象名['新方法名'] = 新匿名函数
3. 删
(1)delete 对象名.属性名
delete 对象名.方法名
delete person.age
delete person.sing
(2)delete 对象名[属性名]
delete 对象名[方法名]
delete person['sex']
delete person['my-name']
delete person['play ball']
遍历对象 for in循环(k 是获得对象的属性名,对象名[k] 是获得属性值)
for (let k in obj) {
console.log(k) // 打印属性名
console.log(obj[k]) // 打印属性值 注意:k不能加引号,因为k是动态的
console.log(obj['k']) // 加引号找的是对象obj里属性名为k的值,结果为undefined
}
let arr = [{uname: '三剑客',age: 18,sex: '男'},
{uname: '傅斯年',age: 20,sex: '女'},
{uname: '妲己',age: 34,sex: '男'}]
for (let i = 0; i < arr.length; i++) {
console.log(arr[0]) 获取数组里的第一个元素
console.log(arr[0].uname) 获取数组里的第一个对象元素里的属性
console.log(arr[i])
console.log(arr[i].uname)
}
Math对象的方法 | 作用 | 举例 | |
---|---|---|---|
random | 生成0-1之间的随机数 (包含0不包括1) | 取 [n-m] 之间随机整数 Math.random() * (max - min + 1)) + min |
|
ceil | 向上取整(不会四舍五入) | Math.ceil(1.1) → 2 Math.ceil(1.5) → 2 |
|
floor | 向下取整(不会四舍五入) | Math.floor(1.1) → 1 Math.floor(1.5) → 1 |
|
round | 就近取整,四舍五入(.5往大取整) | Math.round(1.1) → 1 Math.round(1.5) → 2 Math.round(1.9) → 2 Math.round(-1.1) → -1 Math.round(-1.5) → -1 Math.round(-1.9) → -2 |
|
max | 找最大数 | 传入的是多个数字,不是数组(利用剩余函数) | let arr = [1, 5, 9, 45] console.log( Math.max(...arr) ) |
min | 找最小数 | Math.min(1, 5, 9, 45) | |
pow | 幂运算 | Math.pow(2,3) → 8 (2的3次方) |
|
abs | 绝对值 | ||
PI | 圆周率 π |
// 封装随机数函数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操', 'pink老师']
// 生成1个随机数 作为数组的索引号
let random = getRandom(0, arr.length - 1)
document.write(arr[random])
(1)随机RGB颜色
// 封装随机RGB颜色函数
function getColor() {
let r = Math.floor(Math.random() * 256)
let g = Math.floor(Math.random() * 256)
let b = Math.floor(Math.random() * 256)
// 返回值的2种形式
// 1. 直接返回rgb内的格式,若返回数组会比较麻烦 rgb(12,12,12)
return `${r},${g},${b}`
// 2. 返回数组
// return [r,g,b]
}
// 调用函数
let color = getColor()
document.write(``)
// document.write(``)
(2)随机16进制颜色
// 封装随机16进制颜色函数
function getColor() {
// 将 0-9,a-f (可数、有索引号方便操作)放入到数组中 注意:a-f要用引号
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']
let str = '#'
// 循环6次(因为#后是6位数),筛选出6个随机数 #ffffff
for (let i = 0; i < 6; i++) {
// index表为索引值,索引值0-15 取[0,15]随机整数
let index = Math.floor(Math.random() * (arr.length)) // 15+1 = 16 = arr.length
// #与[0,15]随机整数拼接
str += arr[index]
}
// 返回拼接后的字符串
return str
}
// 调用并输出函数
let color = getColor()
console.log(color)
(3)传参返回随机RGB颜色,不传参则返回随机16进制颜色
function getColor(flag) {
if (flag) {
// 返回rgb颜色
}else {
// 返回16进制颜色
}
}
let flag=prompt('传实参或不传实参')
getColor(flag)
/* getColor(true)
getColor() */
(4)RGB颜色和16进制颜色之间的相互转换
// 获取随机数
let target = Math.floor(Math.random() * 10) + 1
// 确定循环次数用for循环,不确定次数用while循环
while (true) {
let num = +prompt('请猜1~10之间的数字:')
if (num > target) {
alert('猜大了')
} else if (num < target) {
alert('猜小了')
} else {
alert('正确!')
break
}
}
语法 | 作用 | 注意 | |
---|---|---|---|
获取DOM对象 | document.querySelector('选择器') | 选中匹配的第一个元素,获取单个元素 | 选择器要加引号,不加为变量; 如果获取不到会返回null |
document.querySelectorAll('选择器') | 选中匹配的多个元素,获取伪数组 (要经过遍历给伪元素的项进行修改) |
||
其它获取DOM对象的方法 | |||
document.getElementById('ID名') |
|||
document.getElementsByTagName('标签名') |
伪数组 | ||
document.getElementsByClassName('类名') |
伪数组 | ||
document.documentElement |
获取html标签 | ||
document.body | 获取body标签 | ||
id名可放在前面 | id名.document.querySelector('选择器') | 选中id名中符合选择器要求的第一个元素 | |
id名.document.querySelectorAll('选择器') | 选中id名中符合选择器要求的多个元素 | ||
选择器 不支持伪元素选择器,支持部分伪类选择器 |
语法 | 区别 | 注意 |
---|---|---|
对象.innerText = '修改的内容' | 只识别文本,所有内容原样输出 |
不加=则为获取修改的内容,加=则为赋值(修改内容),不能修改表单标签 |
对象.innerHTML = '修改的内容' | 可以解析标签 |
|
document.write() | 只能将文本内容追加到 前面的位置; 文本中包含的标签会被解析 |
随机点名抽奖
抽中的是:名字
样式 | 优缺点 | 用于 | |
---|---|---|---|
修改元素固有属性 | 元素.属性名 = '新属性值' | href、title、src pic.src='路径' |
|
修改元素样式属性 | 元素.style.属性名 = '新属性值' | 复合属性名用小驼峰(去掉-横线,第二个单词首字母大写) | a.style.color = 'red' |
用类名修改元素 (用于修改很多元素样式时) |
元素.className='类名' | 因为class在JS中是关键字 弊端:会覆盖原来的类名,适用于1个类名的操作 |
|
元素.classList.add='类名' 元素.classList.remove='类名' 元素.classList.toggle='类名' 元素.classList.contains='类名' |
添加类名/ 删除类名/ 切换类名(有就删除,没有就添加)/ 是否包含类名 (适用于多个类名,不影响以前类名) |
||
修改表单元素属性 | 元素.属性名 = '新属性值' (和固有元素修改相同) |
disabled 禁用(只用于表单) checkbox 单、多选默认选中 selected 下拉列表默认选中 readonly 只读 |
input.type = 'text' inp.value = 'abc' // disabled 禁用 inp.disabled = true //禁用 inp.disabled = false //解除禁用 console.log(inp.disabled) //判断是否禁用 // checked 默认选项 inp.checked = true inp.checked = false inp.checked |
当我们刷新页面,页面中的图片随机显示不同的图片
两种定时器对比:
定时器(间歇函数、间歇定时器、重复性定时器)可实现 每隔一段时间需要自动执行一段代码(即,每隔一段时间调用一次函数)
1. 开启定时器 注意:函数名后不能加括号,时间是以毫秒为单位 1s=1000ms
setInterval(函数名,时间)
2. 关闭定时器 注意:必须要有定时器名字才可以清除定时器(在开启定时器时,默认返回定时器标识)
clearInterval(定时器标识)
第1张图的描述信息
延时函数只执行一次。
1.开启延时函数 使用规范与间歇函数相同
setTimeout(函数,延迟的时间)
2.关闭延时函数
clearTimeout(定时器标识)
递归函数:函数内部调用其自身
时间
事件:用户的行为、动作(点击,双击)
事件监听:一旦事件源被事件触发,就立即调用一个函数做出响应。
事件源.addEventListener('事件类型',函数)
事件监听的三要素:
举例:
事件分类 | 书写 | 触发条件 | |
---|---|---|---|
鼠标事件 (鼠标触发) |
click | 单击 | |
dblclick | 双击 | ||
mouseenter | 鼠标经过 | ||
mouseleave | 鼠标离开 | ||
mousemove | 鼠标移动 | ||
mouseup/down | |||
焦点事件 (表单获得/失去光标) |
focus | 获得光标 | 用于表单元素 |
blur | 失去光标 | ||
文本事件 (表单输入时触发) |
input | 用户输入时触发 如,textarea |
|
change | 当用户更改、 | ||
键盘事件 (按键触发) |
keydown | 键盘按下 (所有按键都会触发) |
|
keyup | 键盘抬起 | ||
keypress | 键盘按下 输出按键(除了ctrl/shift/alt 操作按键)会触发 |
自动触发事件 事件源.事件类型()
事件源.on事件 = function() { } (有的浏览器可能不支持)
DOM L2 事件源.addEventListener(事件类型, 事件处理函数)
区别:
(1) L0
同类型的事件,后面注册的事件会覆盖前面的;
无法开启事件捕获;
移除事件 事件源.on事件类型=null
(2) L2
同类型的事件,后面注册的事件不会覆盖前面的;
可开启事件捕获,语法:事件源.addEventListener(事件类型, 事件处理函数, 是否使用捕获);
移除事件 事件源.removeEventListener(事件类型, 事件处理函数名称)
定义:事件对象是事件触发时产生的对象,事件对象中存了事件触发时的相关信息.
元素.addEventListener('click',function (e) { })
作用 | 事件对象的属性名 | 说明 |
---|---|---|
获取当前的事件类型 | type | |
获取鼠标位置 | clientX/clientY | 获取光标相对于浏览器可见窗口左上角的位置 |
pageX/pageY | 获取光标相对于文档(document)左上角的位置 | |
offsetX/offsetY | 获取光标相对于当前DOM元素(事件源)左上角的位置 | |
键盘 | key | 获取按下的是哪个键,如:A |
keyCode | 键码值,转换成二进制的数字 | |
ctrlKey shiftKey altKey |
判断按下是否是ctrl/shift/alt | |
获取目标元素 (即触发事件的元素) |
target | 获得真正触发事件的元素 |
需求:一张图片一直跟着鼠标移动
事件流:事件触发后的流程
事件流的两个阶段:捕获阶段、冒泡阶段
事件冒泡:
事件捕获:
段落
事件对象.stopPropagation()
鼠标经过事件的两种写法:
mouseenter 和 mouseleave 没有冒泡效果
mouseover 和 mouseout 会有冒泡效果
如,链接点击不跳转,表单域的不提交
事件对象.preventDefault()
事件对象.target 获取目标元素(即触发事件的元素)
步骤:
li*10{$}
1. 获取元素
let area = document.getElementById('area') // 文本框
let useCount = document.querySelector('.useCount') // 包含数字的span
2. 监听事件
area.addEventListener('input',function(){
// 将useCount的内容改为 用户输入的字符串的长度(字符串也可以遍历)
useCount.innerHTML=area.value.length
})
用户点击全选,则下面复选框全部选择,取消全选则全部取消,文字对应变化
查找... | 写法 | 注意 |
---|---|---|
父节点 | 子节点.parentNode | 返回最近一级的父节点 找不到返回为null 注意:子节点.parentNode.parentNode 爷爷(可以连点) |
子节点 | 父节点.childNodes | 获取所有的子节点(伪数组),包括文本节点(空格、换行)、注释节点等 |
父节点.children | 获取所有的元素子节点(伪数组) | |
父节点.firstElementChild | 第一个 / 最后一个 元素子节点 |
|
父节点.lastElementChild | ||
父节点.firstChild | 第一个 / 最后一个 子节点(可能是 #text) |
|
父节点.lastChild | ||
属性: (1)nodeType 节点类型 如,div.childNodes[0].nodeType 是标签节点返回1,是属性节点返回2,是文本节点返回3 (2)nodeName 节点名称 如,div.childNodes[0].nodeName 是文本节点返回#text,是标签节点返回大写标签名 |
||
兄弟节点 | 节点.nextElementSibling |
后 / 前 一个元素节点 |
节点.previousElementSibling | ||
节点.nextSibling | 后 / 前 一个节点 (可能是 #text) | |
节点.previousSibling |
需求:关闭多个二维码
思路:获取×号并遍历,关闭父元素
创建新节点
let 变量 = document.createElement('新节点的标签名')
1. 追加节点—在父元素内部的最后创建节点
父元素.appendChild(新节点)
2. 插入节点—在父元素内部的旧节点的前边创建节点
父元素.insertBefore(新节点,旧节点)
将已存在的节点追加/插入到别处,可实现该节点的移动。
需求:将img移到第2个div中
向ul里添加li
要克隆的节点.cloneNode(布尔值)
要删除元素必须通过父元素删除
父元素.removeChild(子元素)
img.parentNode.removeChild(img) // 删除img的父元素里的img,即删除它自身
创建时间日期对象(实例化对象),是一种数据类型,可赋值给变量
new Date(); // 当前时间日期
new Date('1999-9-9 6:6:6'); // 指定时间日期(字符串,用引号引起来)
new Date(1999, 9, 9, 6, 6, 6); // 指定时间日期(数字)
new Date().toLocaleString(); // 将时间输出格式改为本地时间格式,小括号内不加东西
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为 0(1月) ~ 11(12月) |
getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
getDay() | 获取星期 | 取值为 0 ~ 6,0代表星期日 |
getHours() | 获取小时 | 取值为 0 ~ 23 |
getMinutes() | 获取分钟 | 取值为 0 ~ 59 |
getSeconds() | 获取秒 | 取值为 0 ~ 59 |
可以用set对象来设置具体日期,如,setMonth(6) 注意:set无返回值,不能直接赋值给变量;星期无set方法。
时间
时间戳是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的精确的计量时间的方式。
获取1970年到当前时间或指定时间的毫秒数:
1. getTime()方法 可以返回指定时间的时间戳
console.log(new Date().getTime());
console.log(new Date('2000-10-10').getTime()); // 字符串要加引号
2. +new Date() 可以返回指定时间的时间戳
console.log(+new Date());
console.log(+new Date('2000-10-10'));
3. Date.now()
console.log(Date.now()); // 只能获取当前时间
今天是2021年8月28日
下班倒计时
00
:
25
:
20
现在是18:30:00
监听整个页面滚动:
window.addEventListener('scroll', function () { })
注意: 给 window 或 document 添加 scroll 事件
作用:当JS写在head中,添加加载事件,不会找不到DOM元素了。
DOM加载事件比资源加载事件速度快,但有兼容性问题。
load加载事件:当所有资源(如图片、外联CSS和JavaScript等(涉及路径就要加载))加载完毕时触发的事件.
页面加载事件: 给window添加load事件
window.addEventListener('load', function () { })
针对某个资源绑定load事件:
div.addEventListener('load', function () { })
当加载完DOM元素后(不用等待样式表 、图像等完全加载),DOMContentLoaded 事件被触发。
页面加载事件: 给document添加DOMContentLoaded事件
document.addEventListener('DOMContentLoaded', function () { })
当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件.
window.addEventListener('resize', function () {
// 不同屏幕大小,字体大小不同
if (document.documentElement.clientWidth>800) {
document.documentElement.style.fontSize='20px'
}
else{
document.documentElement.style.fontSize='10px'
}
})
作用:回到顶部scrollTop=0
获取宽高 (包含:内容宽高+padding+溢出) |
scrollWidth scrollHeight |
获取元素的内容总宽高(不包含滚动条)返回值不带单位( 只读属性,不能设置) 设置宽高的方式:div.style.width = '600px' |
---|---|---|
获取位置 | scrollLeft scrollTop |
获取元素内容往左、往上滚出去看不到的距离(可设置, div.scrollTop=1000) |
当前页面被卷去的顶部距离
document.documentElement.scrollTop
仿新浪
需求:当页面滚动500像素,就显示返回顶部按钮,否则隐藏, 同时点击按钮,则返回顶部
// 1. 滚动500px按钮显示
let backtop = document.querySelector('.backtop')
window.addEventListener('scroll', function () {
if (document.documentElement.scrollTop >= 500) {
backtop.style.display = 'block'
}
else { backtop.style.display = 'none' }
})
// 2. 点击按钮回到顶部
backtop.addEventListener('click', function () {
document.documentElement.scrollTop = 0
})
获取宽高 (包含:内容宽度+padding+border) |
offsetWidth offsetHeight |
只读属性,不可修改 |
---|---|---|
获取位置 | offsetLeft offsetTop |
获取元素距离自己有定位的上级元素,如无定位上级时参照文档的左、上距离; 只读属性,不可修改; |
需求:当页面滚动到秒杀模块,导航栏自动滑入,否则滑出
思路:滚动条滚动的时候,判断scrollTop是否大于等于模块到文档顶部的距离
我是顶部导航栏
秒杀模块
电梯导航案例
需求:点击可以页面调到指定模块效果
男装/女装
儿童服装/游乐园
电子产品
电影/美食
男装/女装
儿童服装/游乐园
电子产品
电影/美食
获取宽高 (包含:内容+padding) |
clientWidth clientHeight |
只读属性,不可修改 |
---|---|---|
获取位置 | clientLeft clientTop |
获取元素的左边框和上边框宽度; 只读属性,不可修改 |
同步:前一个任务结束后再执行后一个任务(从上到下执行,如,for / while 循环;
异步:(异步处理机制)异步任务没有一定顺序,谁先触发谁先处理;
一般异步任务都有回调函数,如:
等同步(for循环while)执行完才执行异步任务
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环;
过程叙述:同步任务被放到执行栈里先被执行,异步任务被放到异步处理机制中,当某一异步任务被触发时,将该异步任务推到任务队列中,然后被执行栈调取到执行栈中执行;
navigator |
浏览器自身的相关信息 |
---|---|
navigator.userAgent |
检测浏览器的版本及平台; userAgent是navigator的属性 |
http://www.baidu.com/index.html?user=123&pwd=456#abc
location的属性/方法 | 作用 |
---|---|
location | 保存了 URL 地址 |
location.href location.href='网址' |
获取完整的url地址 ( 协议https: 或file本地协议 + 域名/主机IP地址 + 端口 + 路径名 + 参数数据 + hash数据 ) 设置url,实现网页跳转(有后退按钮) |
location.search | 获取地址中携带的参数,符号 ?后面部分 |
location.hash | 获取地址中的哈希值,符号 # 后面部分 |
location.reload() | reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新 |
location.assign('网址') |
加载指定的url,会产生历史记录(前进/后退箭头可用) |
location.replace('网址') |
替换指定的url,不会产生历史记录 |
history.length |
只读属性 返回当前任务中的history个数,包含当前页面在内 |
---|---|
history.back() |
回到前一个页面,等同于上一页按钮 |
history.forward() |
转到下一个页面,等同于下一页按钮 |
history.go(参数) |
history.go(-1) 回到前一个页面,等同于调用 back() history.go(1) 转到下一个页面,等同于调用了 forward() |
screen.width | 屏幕的宽度(单位:像素) |
---|---|
screen.height | 屏幕的高度(单位:像素) |
screen.availWidth |
除去任务栏屏幕的宽度(单位:像素) |
screen.availHeight |
除去任务栏屏幕的高度(单位:像素) |
(1)官网:Swiper中文网-轮播图幻灯片js插件,H5页面前端开发
swiper使用方法:Swiper使用方法 - Swiper中文网
(2)使用方法
下载Swiper(下载Swiper - Swiper中文网) 并放到根目录下 → 分别将package中的 swiper-bundle.min.css 和 swiper-bundle.min.js 移动到根目录下的css和js文件夹中 → 在html文件中引入这两个文件 → 找到要使用的案例,在新窗口打开,右击'查看网页源代码' → 将源代码中的css / html / js 复制到自己的代码中 → 进行修改(可以新添类名;需要什么效果在 API文档 中找即可)
注意:多个swiper同时使用的时候, 类名需要注意区分;
特点:
localStorage.setItem('键名', '值')
注意:键名相同会覆盖,存起来变成字符串类型
localStorage.getItem('键名');
注意:如果取不存在的数据就是null
localStorage.removeItem('键名');
1. 将复杂类型转成JSON字符串
localStorage.setItem('键名', JSON.stringify(存储复杂类型的变量))
2. 将JSON字符串转成复杂类型(数组/对象)
JSON.parse(字符串)
特点:
对象.getAttribute('属性名') | 获取自定义属性 |
---|---|
对象.setAttribute('属性名', '属性值') | 设置 / 添加自定义属性值 (有这个属性就是更改属性值;没有这个属性就是添加属性) |
对象.removeAttribute('属性名') | 删除自定义属性,无返回值 |
能操作普通属性(index),也能操作H5属性(data-×××) |
H5 只能操作data- 开头的自定义属性 | |
---|---|
对象.dataset.××× | 获取 data-××× 的属性值 |
对象.dataset.××× = 值 | 设置 / 添加自定义属性值 (有这个属性就是更改属性值;没有这个属性就是添加属性) |
正则表达式是用于匹配、查找字符串中的字符组合的模式。
作用:表单验证(匹配)、过滤敏感词(替换)、字符串中提取关键词(提取)
正则表达式查询工具 |
---|
菜鸟工具:正则表达式在线测试 | 菜鸟工具 |
jQuery正则表达式 |
正则测试工具:在线正则表达式测试 |
方式1:
let 变量名 = /内容/
方式2:
let 变量名 = new RegExp(/内容/)
test() 方法 判断是否包含符合正则的字符串
(布尔值)
正则变量名.test('被检测的字符串')
/正则内容/.test('被检测的字符串')
exec() 方法 查找符合正则的字符串(数组、null)
正则变量名.exec('被检测的字符串')
/正则内容/.exec('被检测的字符串')
元字符分类 |
符号 | 含义 | 举例 | |
---|---|---|---|---|
边界符 | ^ | 以…为开头 | ^abc |
|
$ | 以…为结尾 | abc$ |
||
^abc$ | ^与$同时使用,具有精确匹配的含义 指的就是 字符串abc |
|||
量词符 | * | 出现零次或更多次(>=0) | 与$相同,写在字符后面; /^[a-zA-Z0-9-_]{6,16}$/ 逗号左右两侧不要打空格; |
|
+ | 出现一次或更多次(>=1) | |||
? | 出现零次或一次(0||1) | |||
{n} | 出现n次 | |||
{n,} | 出现n次或更多次(>=n) | |||
{n,m} | 出现n次到n次 [n,m] | |||
字符类 | 字符集合 | [ ] | 多选一 |
[男|女] 不表示男或女,表示'男''|''女' [a-zA-Z] 表示大小写 [^a-z] 匹配除了小写字母以外的字符 [^a-zA-Z0-9_-] |
[ ] 里面加上 - 连字符,表示范围 | ||||
[ ] 里的 ^ 为取反 | ||||
其它字符 | .(点) | 除换行符(\n)之外的任何单个字符 | ||
( ) | 一组 | ^(.|\n)$ 任意单字符,|表示或 |
||
预定义类 | \d | [0-9] | 日期格式: ^\d{4}-\d{1,2}-\d{1,2} |
|
\D | [^0-9] | |||
\w | [a-zA-Z0-9_] | |||
\W | [^a-zA-Z0-9_] | |||
\s | [\t\r\n\v\f],空格(包括换行符、制表符、空格符等) | |||
\S | [^\t\r\n\v\f] |
i | 忽略大小写,ignore |
---|---|
g | 全局匹配,global |
m | 多行匹配 |
/表达式/修饰符 写在正则表达式的后面 |
字符串.replace('旧','新') // 旧 可直接写需替换的文字,也可用正则表达式来表示
字符串.replace(/正则表达式/,'需替换的文本')
str.replace(/c/ig, '&&') // 把字符串str里全部的c和C替换成&&
对象和对象之间的相互配合。
字面量创建对象(一眼就可看出是对象)
let obj = {
属性名:属性值 键值对 成员
uname : 'SHY',
age : 22,
eat : funtion () {console.log('eat')}
}
访问属性:
对象.属性:访问固定属性
对象['属性']:动态属性
访问方法:
对象.方法()
函数如果没有写return、或者函数写了return后面不写值,都是返回undefined
遍历对象
for-in中为什么用[k]:k是变量,要用动态访问
for-in也可以遍历数组
let arr = ['red', 'blue', 'yellow', 'pink'];
for ( let k in arr ) {
console.log( arr[k] );
}
构造函数就是函数,要和new一起使用
(1)内置的构造函数
大写
new Object(); 创建对象 ,对象中的成员是无序的
// 创建对象
let obj = new Object();
// 添加属性:
obj.uname = '阿飞';
obj.age = 22
// 添加方法:
obj.fei = function () {
console.log('方法');
}
new Date(); 创建日期
new Array(); 创建数组
(2)自定义构造函数
function Person (uname, age, sex) {
// 设置对象公共成员:
// 设置对象的属性
this.uname = uname; // 在构造函数中,this指向当前实例化对象
this.age = age;
this.sex = sex;
// 设置对象的方法
this.eat = function () {
console.log('eat');
}
this.say = function () {
console.log('shuohua');
}
}
// 实例化对象 new一次创建1个对象
let obj = new Person('阿飞', 22, '男');
console.log( obj );
let o = new Person('带土', 21, '女');
console.log(o);
3.
instanceof:是否是某个构造函数的实例;
constructor:用于指回构造函数的
对象 instanceof 构造函数 返回值为 true、false
适用于数组,对象
对象 instanceof Object
对象 instanceof Array
4.
实例成员:给实例对象添加的成员,只能由实例对象使用
静态成员:构造函数身上添加的成员,只能由构造函数使用
解构赋值是一种快速为变量赋值的简洁语法 ,分为数组解构、对象解构两大类型。
中心思想:一一对应; 变量用[]包起来
let arr = ['张飞', '关羽', '赵云', '马超', '林冲', '吕布']
1. 正常模式(变量数=数组的长度)
let [a, b, c, d, e, f] = arr // 变量对应的值:张飞 关羽 赵云 马超 林冲 吕布
2. 变量数<数组的长度
let [a, b, c, d] = arr // 变量对应的值:张飞 关羽 赵云 马超
3. 变量数>数组的长度 (多余的变量被赋值为 undefined )
let [a, b, c, d, e, f, g, h] = arr // 变量对应的值:张飞 关羽 赵云 马超 林冲 吕布 undefined undefined
4. 剩余值 (剩余值只能置于最末位)
let [a, b, ...c] = arr // 变量对应的值:张飞 关羽 ['赵云', '马超', '林冲', '吕布']
5. 按需取值(不需要取的数组元素用 逗号占位 即可)
let [, b, , , e] = arr // 变量对应的值:关羽 林冲
6. 多维数组解构
let [, b, [c, , e,]] = ['张飞', '关羽', ['赵云', '马超', '林冲', '吕布']] // 变量对应的值:关羽 赵云 林冲
多维数组:
arr[2][1] arr[2][3]
let arr = ['张飞', '关羽', ['赵云', '马超', '林冲', '吕布']]
arr[0] arr[1] arr[2][0] arr[2][2] // 对应的索引值
let uname = 'SHY'
let { uname: myname, sex, index = 666, dog: { uname: dogname, sex: dogsex } } = {
uname: '秀儿',
age: 18,
sex: '男',
dog: {
uname: '大黄',
age: 2,
sex: '公',
}
}
console.log(myname, sex, index, dogname,dogsex)
// 变量对应的值为:秀儿 男 666 大黄 公
let uname = '小张';
let age = 18;
// 创建函数
let obj = {
uname, // uname:uname
age, // 属性名:变量名 可以直接简写
index: 8, // 不引用变量的照常写
score: 100,
eat() { console.log('123') }, // eat : function(){ }
go() { console.log('gogogo') } // 方法简写:方法名(){ }
}
// 1. 获取元素 tabs是tab导航条,mains是每个导航条对应的内容
let tabs = document.querySelectorAll('.tab li')
let mains = document.querySelectorAll('.products .main')
// 2. 遍历伪元素
for (let i = 0; i < tabs.length; i++) {
// 3. 在遍历里添加监听事件
tabs[i].addEventListener('click', function () {
// 5. 排它思想 在步骤4之前,先把带有类名的清除(再遍历一遍)
for (let i = 0; i < tabs.length; i++) {
// 注意:伪元素进行修改/设置要加[]
tabs[i].classList.remove('active')
mains[i].classList.remove('active')
}
/* // 4-2. 排他思想 让之前带有类名的div隐藏
// 因为i和j是一一对应的,所以可以写在步骤5中
for (let j = 0; j < mains.length; j++) {
mains[j].classList.remove('active')
} */
// 4-1. 点击tab选项时,给tabs/mains添加类名
// tabs[i].classList.add('active')
this.classList.add('active')
mains[i].classList.add('active')
})