一.什么是js
与网页进行交互的脚本语言,有一定的逻辑性
脚本语言:所写即所得,无需编译,只需要解析
二.js的组成部分
1.DOM 文档对象模型 Document Object Model
用于操作网页上的元素,给元素添加样式,行为
2.BOM 浏览器对象模型 Browser Object Model
操作浏览器的前进,后退,刷新,打印...
3.ECMASCRIPT
定义语法规范,例如关键字,保留字的使用
三.变量的命名规则
1.由字母\数字\下划线\$组成
2.不能以数字开头
3.不能用关键字\保留字
4.严格遵循大小写
5.遵循驼峰命名原则 大驼峰(类,构造函数),小驼峰(变量,形参)
6.语义化(见名知意 )
四.js输出三种写法
1.在控制台打印内容
console.log()
2.在页面上显示
document.write()//把内容渲染成为页面上的元素
3.对话框
alert()
五.数据的类型
js在ES3之前有6大数据类型
1.字符串类型
由双引号或单引号组成
var uname1="Tom" console.log(uname1) console.log(typeof (uname1)) var uname2='Jerry' console.log(uname2) console.log(typeof (uname2)
2.数值类型 number
var num = 2.3 console.log(num) //2.3 console.log(typeof num) //number var age = 100 console.log(age) //100 console.log(typeof age) //number
3.boolean类型
bool类型的值,只有2个,true/false, 真或假
var flag=true;//真 console.log(flag);//true console.log(typeof flag)
4.undefined类型
//undefined 未定义类型, 声明变量,未赋值,就是undefined var age console.log(age) //undefined console.log(typeof age) //undefined
5.null
//null 空地址 var o = null console.log(o) console.log(typeof o) //objet 原本应该打印的null,在这里打印了object,是一个js遗留的问题
6.object类型
object类型包含 (Array,Function,Date..) 都属于对象类型
六.js是弱类型语言
弱类型特点:
●类型可以被随意修改
●声明变量可以不赋予初值
七.特殊的类型和特殊的值
特殊的类型: null和 undefined
null派生了undefined null==undefined null是js里的顶级对象
特殊的值: NaN ,属于number类型
NaN //not a number 不是一个数值
0/0 NaN
"a"*10 NaN
八.运算符
1.拼接运算符
2.算数运算符
+ , - , * , / ,%
3.赋值运算符
+=, -=,*=, /=, %=
4.逻辑运算符
&& || !
5.关系运算符
>, >= ,< , <=, ==, ===, != ,!==
6.一元运算符
a++ ,++a
a-- ,--a
7.三目运符 (三元)
? :
8.位移运算符
<< >> >>>
类型转换
1.进制转换
二进制
八进制
十六进制
二进制转十进制
八进制转十进制
十六进制转十进制
八进制转十六进制
2.bool类型转换
1.字符串转bool
非空字符串为TRUE,空字符串为false
2.数值类型转bool
非0为TRUE,0和NaN为false
3.null和undefined始终为false
4.object转bool
不为null,则为TRUE
3.运算符
1.算数运算符 +,-,*,/,%
除了 "+"以外,其他的都产生隐式转换
"10"-2 -> 10-2
2.赋值运算符 +=,-= ,*=,/=,%=
3.关系运算符
>,>=,<,<=,==,!=,===,!==
==只比较值不比较类型,会隐式转换
=== 全等于,恒等于 值和类型都要一致
!= 不等于
!== 不全等于,因为类型不一致
4.逻辑运算符
&& || !
&& 找假,只要有假就为false
|| 找真,只要有真就为TRUE
! 真为假,假为真
短路运算符 -- && ||
5.一元运算符 ++ --
a++ 先取值 后运算 ++a 先运算后取值
6.三目运算符 ? :
条件满足走最近的,条件不满足走最远的
7.位移运算符 拼接
>> 右移 << 左移 转成二进制
8.字符串运算符
+
比较运算符的规则
字符串与字符串比较的是ASCII码
字符串与数值比较,字符串会隐式转换为数值
字母与数值无法计较
数值与数值直接比较大小
0~9 48~57
a~z 65~90
A~Z 97~122
优先级: . [] () 最高
&& 比 || 优先级高
4.逻辑分支
顺序 分支 循环
分支是同步行为 同步:按照顺序一步一步执行
分支:单分支 if(){}
双分支 if(){}else{}
多分支 if(){}else if(){}else{} if 嵌套
Switch
Switch的比较是全等于 ===
Switch建议带break,防止穿透
switch的应用场景: 表达式为固定值, 不能判断范围
switch(表达式){
case 常量1:
break;//防止穿透
...
default:
}
switch(x)
{
case 0...99: //等价于 0<=x && x<=99;
xxxxxx;
xxxxxx;
break;
case 100...199: //等价于 100<=x && x<=199;
xxxxxx;
xxxxxx;
break;
default:
xxxxxx;
break;
}
var x=parseInt(prompt('积分'))
switch(true){
case x<2000:
console.log('9折')
break
case x<4000&&x>=2000:
console.log('8折')
break
case x<8000&&x>=4000:
console.log('7折')
break
case x>=8000:
console.log('6折')
break
default:
console.log('err')
}
一些补充知识
Number()在转换 ""的值是0
parseInt(),parseFloat()转换空字符串 ""是NaN
Math.pow(x,y) 平方
toFixed(n) 保留n位小数
若有收获,就点个赞吧
循环
1.while
特点:先判断后执行
while(判断条件){ 执行语句 自加 } var n=1 var res=0 while(n<=100){ res+=n++ } console.log(res)
do...while
特点:先执行后判断
do{ 执行语句 自加 }while(判断)
for
注意死循环
注意: 有多个判断是否结束循环根据最后一个判断条件,最后一个判断条件不满足即结束
for(;;){ 执行语句 } //根据最后一个判断条件,最后一个判断条件不满足即结束 for(var i=0,j=0;i<5,j<10;i++,j++){ console.log(i*j)//81 }
break和continue
break的功能:
1,在switch语句中使流程跳出switch结构。
2,在循环语句中使流程跳出当前的循环
注意:
1, 如果已执行break语句,就不会执行循环体中位于break后的语句。
2, 在多层循环中,一个break语句只向外跳一层
continue的功能:
只能在循环语句中使用,使本次循环结束,即跳过循环体中下面尚未执行的语句,接着进行下次是否执行循环的判断。
注意:
1, continue语句只能用在循环里。
2, 对于 while 和 do-while 循环,continue 语句执行之后的动作是条件判断;对于 for 循环,随后的动作是变量更新。
总结:
break可以用在Switch分支中(防止穿透)和循环中
continue只能用在循环中
break在循环中结束就近的循环,也可以结束指定是循环
continue结束当前循环,不会结束整个循环
break和continue后面的都不会被执行
a:for(var i=0;i<5;i++){ console.log('A外层') b:for(var j=0;j<5;j++){ console.log('B外层') break a //结束指定循环 } }
补充:bigInt 大整型
函数
函数介绍
JS函数: 函数就是把特定功能的代码抽取出来,使之成为程序中的一个独立实体
好处:
使程序变得更简短而清晰 , 提高可读性
有利于程序维护
代码复用
函数的分类:
系统函数 内置函数 和 自定义函数
自定义函数:
有参有返回值(标准)
有参无返回值
无参无返回值
无参有返回值
function 函数名(形参) { 代码块; }
注意:
1, 必须使用function关键字, 且为小写, 函数名可以自己给定
2, 函数名的命名规则和变量名一致
3, 函数名后必须写圆括号()
4.如果函数没有return关键字,该函数默认返回undefined,return,返回结果,并且终止函数,,return后面的代码不执行
5.形参,形式的参数,只表示一个占位,默认值undefined,属于局部变量,根据实参的类型,确定形参的类型
Arguments
1.arguments 只能在函数内部使用
2.arguments 是一个伪数组,实质是一个对象,类似数组
3.它的使用与数组一样,用于动态接收实参
伪数组也可以通过下标取值
function cal() { for (var i = 0, res = 0; i < arguments.length; i++) { res += arguments[i] } return res } var sum = cal(10, 45, 36, 19) console.log(sum); //实现重载效果 function hello() { if(arguments.length==1){ return '你好' } if(arguments.length==2){ return "大家好" } } var res1=hello(1) var res2=hello(3,2) console.log(res1); console.log(res2)
JS里没有重载
作用域
作用的范围,分为局部变量和全局变量
局部变量:
定义在函数内部的变量,这个变量只能在函数内部使用,即作用域范围只是函数内部,另外,形参也是局部变量.
全局变量:
定义在函数外部的变量,这个变量在任何函数中都有效,即作用域范围是当前文件的任何地方.
注意:
在定义变量时, 如果不写关键字var也是合法的, 且是全局变量, 但是这样写不安全,容易在其他地方被更改, 所以我们在函数中写变量要加上var
作用域链
基于全局变量和局部变量,再找一个变量的过程,优先查找局部变量
如果局部不存在,去外层的函数内部查找,如果外层也没有,就去全局查找,这个过程就是作用域链
由内向外,从局部到全局寻找变量的过程
函数的相互调用
兄弟函数可以相互调用,但是没办法调用兄弟函数的子函数,兄弟函数的子函数可以调用兄弟函数
function fnA() { console.log('AAA'); } function fnB() { fnA()//能够调用兄弟函数fnA console.log('BBB'); function fnb() { console.log('bbb'); fnA()//能够调用全局的函数fnA } fnb() } fnB()
事件驱动
js是典型的事件驱动编程
通过事件执行函数,事件就是一种交互行为
<button id="btn">点击我</button> <script> var oBtn=document.getElementById('btn') //方式一:匿名函数 oBtn.onclick=function(){ console.log('我被执行了') } //方式二 oBtn.onclick=click//点击后()自动被添加,函数执行 //oBtn.onclick=click()页面加载完成,函数就执行,点击无效果 function click() { console.log('我被执行了') } //方式三:箭头函数 oBtn.onclick=()=>{ console.log('我被执行了') } </script>
设置值与获取值
<button id="set">设置</button> <button id="get">获取</button> <input id="txt" value=""> <script> var oSet=document.getElementById('set') var oGet=document.getElementById('get') var oInput=document.getElementById('txt') oSet.onclick=()=>{ oInput.value="周哈哈" } oGet.onclick=()=>{ var str=oInput.value console.log(str) } </script>
注意: .value获取的值始终是字符串
this
window 对象,顶级函数
函数内的this默认指向window对象
funtion fn(){ //函数内的this默认指向window对象 console.log(this) } var oBtn=document.getElementById('btn') oBtn.onclick=()=>{ console.log(this); //匿名函数绑定给了oBtn,所以this就是oBtn,oBtn就是按钮 }
递归/数组
递归
函数自己调用自己,必须有临界点
循环能做的递归都可以做,递归都可以实现,但是递归的性能比较差
常见的递归使用场景
1.对象深拷贝
2.在nodejs下,磁盘文件的遍历
3.后台管理系统的权限加载(动态路由)
4.多级菜单
数组
一组数据(一般情况下是相同类型的数据,),可以是任意类型,并且可以随意扩容
数组的作用
使用单独的变量名来存储一系列的值, 数组是特殊的变量,它可以同时保存一个以上的值。
创建数组的方式
1.构造函数创建数组
var arr =new Array() var arr = Array()
2.数组的字面量表达式(简写)
var arr=[]
创建数组,初始值
var arr=new Array(10,20)//10表示数组的长度
数组的length属性
数组长度可以被修改,修改长度会丢失数据
数组的使用
使用数组就是在使用数组的每个元素,因为数组相当于若干个相同类型的变量。
遍历数组: 之前我们讲过通过下标获取单个数组元素, 但有时候我们需要批量使用数组, 这个时候我们需要遍历整个数组.
1, 普通for循环
for(var i=0; i<arr.length; i++){ console.log(arr[i]); }
2, for...in遍历 用于遍历数组或者对象
for(var i in arr){ console.log(arr[i]); }
数组的方法
方法的作用,方法的参数,方法的返回值
1.push() 往数组的最后位置添加成员,返回数组的新长度
2.pop() 删除数组的最后一位成员,返回被删除的成员
3.shift() 删除数组的第一个,返回被删除的元素
4.unshift() 往数组的第一个位置添加成员,返回数组的长度
isNaN() true不是数值类型,false是数值类型
5.Array.isArray() true是数组,false不是数组
6.sort() 排序
sort方法默认根据ASCII码,进行排序
解决办法,在sort方法里加入一个回调函数
回调函数里,return a-b 升序, return b-a 降序
7.reverse() 倒序
8.slice() 截取,不会改变原来数组
slice()的第一个参数表示开始位置,第二个参数表示结束位置,但截取的数据不包括结束位
slice()只有一个参数时表示从起始位置截取到最后一位
9.splice()
2个参数:删除,返回一个数组,数组里就是被删除的数,第一个参数表示删除的位置,第二个参数表示删除的数量
3个参数:第二个参数是0,表示插入;第二个参数是1以上,表示替换,数字表示替换的数位
10.concat()
追加数据, 创建一个新数组, 不改变原数组
合并数组,也可以合并其他的,还能做浅拷贝
11.join()
连接数组中的元素, 并返回连接后的字符串, 不传参则以逗号连接
默认以','隔开,返回的是字符串
12.indexOf()
找到了就返回下标,找不到返回-1,默认第二个参数是0,如果第二个参数不为0,则表示搜索的起始位置
indexOf(4,4)表示从下标4开始寻找值为4的数的下标
//push var arr=[11,22,33] console.log(arr.push('aa','bb'))//5 console.log(arr)//[11, 22, 33, 'aa', 'bb'] //pop var arr=[11,22,33] console.log(arr.pop())//33 console.log(arr)//[11, 22] //shift var arr=[11,22,33] console.log(arr.shift())//11 console.log(arr)//[22, 33] //unshift() var arr=[11,22,33] console.log(arr.unshift('aa',123))//5 console.log(arr)//['aa', 123, 11, 22, 33] //Array.isArray() console.log(Array.isArray([]))//true console.log(Array.isArray(123))//false console.log(typeof [])//object //sort() var arr=[4,3,9,6,2,7,11] console.log(arr.sort())//[11, 2, 3, 4, 6, 7, 9] var arr=[9,6,4,8,0,3,7,6,15] console.log( arr.sort((a,b)=>{ // return a-b //升序 return b-a //降序 [15, 9, 8, 7, 6, 6, 4, 3, 0] }) ); //reserve var arr=[1,2,3] console.log(arr.reverse());//[3, 2, 1] //slice() var arr=[1,2,3,4,5,6,7,8,9,45] console.log(arr.slice(3,5));//[4, 5] console.log(arr.slice(3));//[4, 5, 6, 7, 8, 9, 45] console.log(arr);//[1, 2, 3, 4, 5, 6, 7, 8, 9, 45] //splice() //删除 var arr=[11,22,33,44,55,66] console.log(arr.splice(3,1))//[44] console.log(arr);// [11, 22, 33, 55, 66] //插入 var arr=[11,22,33,44,55,66] arr.splice(3,0,00,99) console.log(arr);//[11, 22, 33, 0, 99, 44, 55, 66] //替换 var arr=[11,22,33,44,55,66] //arr.splice(3,1,'tom')//[11, 22, 33, 'tom', 55, 66] arr.splice(3,2,'tom','jerry','alice')//[11, 22, 33, 'tom', 'jerry', 'alice', 66] console.log(arr) //concat var arr1=[11,22,33] var arr2=[11,22,55] var arr3=arr1.concat(arr2) var arr4=arr1.concat(arr2,'!',123456) console.log(arr1);//[11, 22, 33] console.log(arr2);//[11, 22, 55] console.log(arr3);//[11, 22, 33, 11, 22, 55] console.log(arr4);//[11, 22, 33, 11, 22, 55, '!', 123456] var arr1=[1.2,3] var arr2=arr1//这不属于数组复制,只是复制了数组的存储地址 var arr1=[4,85,3] var arr2=[] var arr3=arr2.concat(arr1) console.log(arr3)//[4, 85, 3] //join var arr=[2022,7,15] console.log(arr.join());//2022,7,15 console.log(arr.join('-'));//2022-7-15 console.log(arr.join('/'));//2022/7/15 //indexOf var arr=[1,2,3,4,5,6,4,8] console.log(arr.indexOf(4));//3 console.log(arr.indexOf(99));//-1 console.log(arr.indexOf(4,4));//表示从下标4开始寻找值为4的数的下标 //6