参考文献
<script scr=""></script>
变量就是用于存放数据的容器。
var a=1;
变量声明后未赋值,此时的值是undifined
使用未声明的变量会报错
var a=1,b=2,c;
多个变量之间用逗号隔开。
一旦声明不能重新赋值。
例如:春节的日期、中秋节的日期、圆周率...
关键字: const PI=3.14;
分为原始类型和引用类型
原始类型分为数值型、字符串型、布尔型、未定义型(undefined)、NULL(空)
数据被引号包含就是字符串类型;不区分单双引号。
查看一个字符的Unicode编码
console.log( ‘a’.charCodeAt ) //97
在程序中表示真或者假的结果
true/false
常用于一些是否的结果,是否登录,是否注册,是否是会员,是否在售
isLogin=true; isOnsale=false;
声明了变量未赋值,结果就是undefined
用于释放(销毁)一个引用类型的地址,只有一个值null
①数字+字符串:数字被转成字符串
1+'a' //'1a'
②数字+布尔型:布尔型被转成了数字 true->1 false->0
1+true //2
1+false //1
③布尔型+字符串:布尔型转换成字符串
true+'hello' //'truehello'
JS中加号(+)的作用
执行加法运算
执行字符串的拼接
使用- * / 执行运算
尝试将运算符两端转成数值型,如果含有非数字则返回一个NaN(Not a Number),不是一个数字。
NaN类型Number
①将任意类型转为整型
parseInt()
parseInt('1.5a')//1
从开头查找数字,遇到非数字或者小数点;返回前面的数字;如果开头非数字,返回NaN。
②将任意类型转为浮点型
parseFloat()
parseFloat('1.5a')//1.5
转换规则和parseInt类似,区别在于遇到小数点继续往后查找数字。
③将任意类型转为数值型
Number()
Number('1.5a') //NaN
如果要转换的数据中含有非数字,则返回NaN
true->1 false->0
④将数值型和布尔型转为字符串类型
toString()
var num=10;
num.toString(); //'10'
num.toString(16); //a
如果要转换的数据是数值,可以设置进制(8,16,2)
由运算符连接操作的数据,所组成的形式就是表达式
+ - * / %(取余) ++(自增) --(自减)
%取余
++ 自增,在原来的基础之上加1
-- 自减,在原来的基础之上减1
console.log(num++) //先打印num的值,在进行自增
console.log(++num) //先执行自增,再打印num的值
> < >= <= == != ===(全等于) !==(不全等于)
返回一个布尔型的结果
== 只是比较两个值是否相同
===不仅比较值,还会比较类型是否相等
3>'10' //false
数字和字符串比较,字符串要转成数字。
'3'>'10' //true
比较首个Unicode的码,如果首个字符相同,则比较第二个字符。
'3'->51 '1'->49
3>'10a' //false
3<'10a' //false
3=='10a' //false
'10a'->NAN
NaN和任何数比较(> < = >= <= ==)都返回false
NaN==NaN 返回false
&& 关联的两个条件都满足,结果是true,否则false
|| 关联的两个条件都只需满足其一,结果是true,否则false
! 取反 !false取反->true !true->false
逻辑短路
&& 当第一个条件为false的时候,就不需要再执行第二个条件
|| 当第一个条件为true的时候,就不需要再执行第二个条件
在执行运算时候,会把数字转成二进制进行运算
按位与(&) 3&5 上下两位都是1,结果是1,否则是0
按位或(|) 上下两位含有1,结果就是1,否则0
3|5
011
101
111
按位异或(^)上下两位不同为1,相同为0
5^7
101
111
010
按位右移(>>)删除二进制的最后一位,大概变小到原来的一半
7>>1
按位左移(>>)删除二进制的最后添加一位0,增加一倍
= += -= *= /= %=
单目运算符:只需要一个数据或者表达式
a++ a-- !false
双目运算符:只需要两个数据或者表达式
+ - * / % > < >= <= == != === !== && || & | ^ >> << = += -= *= /= %=
三目运算符:需要三个数据或者表达式
条件表达式?表达式1:表达式2
如果条件表达式为true,执行表达式1;
如果条件表达式为false,执行表达式2;
alert() 弹出警示框(消息框)
prompt()弹出提示框(输入框),需要一个变量来接受输入的值;值的类型是字符串类型。
程序 = 算法 + 数据
程序分为顺序执行、选择执行、循环执行
语句1;
if(条件表达式){
语句2
}
语句3;
执行流程:
①执行语句1
②条件表达式,如果为true,执行语句2;false直接跳过
③执行语句3
注意:如果if后的大括号语句中只有一行,是可以省略大括号。
if(age>=18)
console.log('成年人');
在if语句的条件表达式中,有一些值默认就是false
0,NaN,'',undefined,null
语句1;
if(条件表达式){
语句2;
}else{
语句3;
}
执行过程:
①先执行语句1
②要执行条件表达式,如果是true,执行语句2;如果是false,执行语句3
用于判断多种情况:
语句0;
if(条件表达式1){
语句1;
}else if(条件表达式2){
语句2;
}else ...if(条件表达式n){
语句n;
}else{
语句n+1;//以上所有的条件表达式都是false
}
执行流程:
①执行语句0
②执行表达式1
如果条件表达式1是true,执行1,
如果条件表达式1是false,执行条件表达式2
如果条件表达式2是true,执行语句2
如果条件表达式2是false,执行语句n
③以上所有的条件表达式为false,执行语句n+1
是一种特殊的分支语句,可以根据一个表达式的不同值,来选择执行不同的程序。
语句0;
switch(表达式){
case 1://如果表达式的值是1
语句1;
break;//终止,不会再往后执行其他的语句
.......
case n:
语句n;
break;
default:
语句n+1;
}
注意:在case中的和值的比较使用的是全等于比较,值和类型都满足结果才是true。
对比if-else嵌套和switch-case语句
相同点:两者都可以用于多项分支语句。
不同点:if-else可以判断相等或者不相等的情况,适用范围更广一些;switch-case只适用于全等(===)的情况,但是结构上更为清晰,执行效率相对高。
break:结束循环,后续不会再执行其他的循环了
continue:跳过本次循环,继续下一次循环
循环:就是一遍又一遍执行相同或者相似的代码。
循环的两个要素
循环的条件:重复的次数
循环体:重复执行的相同或者相似代码
while(循环条件){ //是一个布尔型的值
循环体
}
do{
循环体
}while(判断条件);
不管循环条件是否为true都会执行一次循环体。
for(初始值;循环条件;i的变化){
3
循环体
}
①执行初始值
②判断循环条件
③如果循环条件是true执行循环体,是false结束循环
④如果执行了循环体,执行i的变化
⑤重新执行第2步
while,do-while,for循环三者之间可以相互嵌套。
九九乘法表:
for (var j=9; j>=1 ; j-- ){
//产生列数
for (var i=j,str=''; i>=1 ; i-- ){
str+=i+'*'+j+'='+(i*j)+' ';
}
//打印一行的拼接结果
console.log(str);
}
parseInt()取整
parseFloat()取小数
typeof()识别类型
分为系统函数和自定义函数
function:功能体,函数,可以接受若干个数据,返回处理的结果。用于封装反复执行的代码。
function 函数名称(){
函数体—要封装的反复执行的代码
}
调用:
函数名称();
function 函数名称(参数列表){ //形参->形式上的参数
函数体
}
调用
函数名称(参数列表); //实参->实际的参数
参数列表:可以是0个或者是多个数据,之间用逗号隔开;创建函数时的参数称为形参,调用函数时的参数称为实参,
调用的时候,实参的值会赋给形参。
形参本质上就是一个声明了的变量,但未赋值。
function 函数名称(参数列表){
函数体
return 返回值;
}
调用:
函数名称(参数列表)
return表示函数执行后,所返回的结果。
注意:
①如果没有return或者return后没有返回值,结果都是undefined。
②return后可以返回任意类型的数据
③return后的所有代码都不会被执行
对比return、break和continue
return 返回结果,用于终止函数的执行,常用于函数中。
break用于结束循环,结束switch语句;
continue 跳过当前循环,继续下一次循环。
变量或者函数的可访问范围
分为两种:
全局作用域:在全局作用域下声明的变量可以在任意位置访问到。
函数(局部)作用域:函数作用域下声明的变量只能在函数内部访问。
块级作用域:ES6新增了let命令,用于声明变量。其用法类似于var,但所声明的变量只在let命令所在的代码块有效。
注意:在函数内部使用var关键字声明的变量是局部变量,而不使用var关键字声明的变量是全局变量。
JS程序在执行前,使用var关键字声明的变量会提升到所在作用域的最前边;但赋值还是在原来的位置。
console.log(a);
var a=1; //var a;这句话会提升到最前面;而a=1还是在当前位置。
函数会提前声明!
函数表达式不会提前声明!
函数和变量类似,也分为全局作用域和函数作用域
全局作用域:在全局作用域下创建的函数可以在任意位置调用
函数(局部)作用域:在函数(局部)作用域下创建的函数只能在函数内部调用。
函数声明提升:
和变量一样,JS在程序执行前,把使用function声明的函数提升到最前边。
function fun(){
return 1;
}
函数调用 fun() 获取函数的返回值(return后的值)
函数名称 fun保存的是函数在堆内存中的地址
递归就是函数自己调用自己本身,依靠条件判断return结束。
例题:求n个数的累加:
function sum(n){
if(n==1){
return 1;
}
return n+sum(n-1)
}
sum(100)
例题:斐波那契数列:
//创建函数, 传递1个参数,使用递归计算斐波那契数列的第n项是多少。
function add(num){
if(num==2){
return 2;
}
return num+num+add(num-2);
}
var res=add(3);
console.log(res);
变量名称和函数名称重复后 如果变量赋值 函数报错,如果变量未赋值函数不会报错
没有名字的函数 function(){
}
创建函数—函数声明
function 函数名称(){
}
var 函数名称=function(形参列表){
函数体
return 返回值;
}
调用:函数名称(实参列表)
对比函数声明和函数表达式的区别
函数声明存在函数提升,在任何的位置都可以调用
函数表达式不存在函数的提升,必须先创建再调用
创建函数(局部)作用域,防止造成全局污染。
(function(){
函数体//就是局部作用域,创建的变量和函数都是不能被外部访问
})();
把匿名函数作为实参传递给形参,此时的形参就是函数名称
function fn(num){
//num就是函数的名称
num();//调用传递的匿名函数
}
fn(function(){
.....
});
encodeURI 对一个URL进行编码 —主要对中文进行编码
decodeURI 对一个已经编码URL进行解码
parseInt 将数据转为整型
parseFloat 将数据转为浮点型
isNaN 检测一个数据是否为NaN 是->true,否->false
isFinite 检测一个数据是否为有限值,是->true 否->false 1/0->Infinity 无限值
eval 执行字符串中的表达式 eval('1+2') ->3
练习:使用提示框弹出输入一组运算,使用eval来执行这组运算。
是一种引用类型的数据,存储在堆内存中。
对象:是一组属性(property)和方法/功能(method)的集合
哪些是对象?
一个手机:属性有颜色,品牌,尺寸,厚度…功能有打电话、发短信、照相、聊天、游戏…
一辆汽车:属性有品牌、外观、车型…功能有代步、撞人、拉货、取暖、乘凉…
(1)JS中的对象:
内置对象:JS提供的
宿主对象:根据不同的执行环境来划分
自定义对象:自己创建的对象
(2)创建自定义对象:
①对象字面量(直接量)
②内置构造函数
③自定义构造函数
使用大括号{}创建空对象
属性名和属性值之间用冒号隔开:
多组属性之间用,号隔开
属性名中引号可加可不加,如果出现特殊字符,必须添加引号
var phone={
color:'red',
'made-in':'china'
};
var book=new Object();创建一个空对象
book.id=103;//给book添加属性,属性名不能添加引号
book['title']='三国演义';//添加属性,属性名必须加引号;如果不加引号会被认为是变量
emp.eid
emp['ename']
如果要获取的属性名不存在,返回的是undefined
获取到对象中每一个属性名,进而获取属性值
for(var key in){
//emp要遍历的对象
//key 要遍历的每一个属性名
//emp[key]通过属性名获取对应的属性值
console.log(emp[key]);
}
'属性名' in 对象 //true->存在 false->不存在
对象.hasOwnProperty('属性名') //true->存在 false->不存在
对象.属性名===undefined //true->不存在 false->存在
var person={
name:'tom',
say:function(){
this.name //指代当前的对象
}
}
person.say();//调用对象中的方法
var a=[元素1,元素2.....]
数组中可以存放任意类型的数据
var car=new Array(5) //初始化一个数组长度为5,可以继续添加第6个元素
new Array(元素1,元素2..............)
访问数组中的元素
数组名称[下标],下标是从0开始
数组名称.length //获取个数
使用数组长度添加一个新的元素
数组[数组.length]=值
数组分为索引数组和关联数组
索引数组:以整数作为下标
关联数组:以字符串作为下标
var arr=[]
arr['eid']=1;
arr['ename']='Tom';
for循环,循环遍历数组元素的下标
var score=[85,79,93];
for(var i=0;i<score.length;i++){
i代表数组元素的下标
scorep[i]下标对应的元素
}
注意:只能遍历索引数组
for-in
for(var key in arr){
key 数组的下标
arr[key] 下标对应的元素
console.log(key+'---'arr[key]);
}
注意:既可以遍历索引数组,也可以遍历关联数组。
API-应用程序编程接口,预先定义好的函数/方法
say:function(){ }
toString() 将数组中的元素按逗号分隔成字符串
join('|') 将数组中的元素按照指定的字符分割成字符串
concat(arr1,arr2,arr3....) 要拼接两个或者更多的数组
slice(start,end) 截取数组中的元素,start开始的下标,end结尾的下标,不包含end本身;负数表示倒数第几个。
splice(start,count,value1,value2.....) 删除数组中的元素;
start开始的下标,count删除的个数,value1,value2....删除后补充的元素。
reverse() 翻转数组中的元素
sort() 对数组中的元素进行排序,默认是按照Unicode码有效达到
对数字排序:
sort(function(a,b){
return a-b; //由小到大
return b-a; //由大到小
});
常用的数组操作:
push() 往数组的末尾添加元素。返回数组的长度
pop() 删除数组末尾的元素 返回删除的元素
unshift() 往数组的开头添加元素,返回数组的长度
shift() 删除数字开头的元素,返回删除的元素
数组中的每一个元素也是数组
var arr=[ [ ],[ ],[ ]..... ]
访问二维数组中的元素 arr[下标][下标]
包装对象:目的是让原始类型的数据也可以像引用类型一样,具有属性和方法
转换字符的意义:
\n 将字符n转义成换行
\t 将字符t转义成制表符(table键)
\' 将引号转成普通的字符
toUpperCase() 将英文字母转为大写
toLowerCase() 将英文字母转为小写
length 获取字符串的长度
charAt() 获取下标对应的字符
charCodeAt 获取某个字符对应的Unicode码
indexOf(value,start) 查找某个字符串的下标,value是要查找的字符串,start开始查找的下标,默认是0,如果找不到返回-1
lastIndexOf (value)查找某个字符串,最后一次出现的下标,找不到返回-1
slice(start,end) 截取字符串,start开始的下标,end结束的下标,不包含end本身;如果end为空,截取到最后
substring(start,end) 截取字符串,start开始的下标,end结尾的下标不包含end本身;如果两个参数是负数,自动转成了0
substr(start,count)截取字符串,start开始的下标,count截取的长度;如果count为空截取到最后。
split(sep分隔符)按照指定的字符分隔为数组。sep—是分隔符
String.fromCharCode(index) 获取任意Unicode码对应的字符
作用:用于查找、替换字符串。
replace(value1,value2) 查找并替换。value1要查找的字符串,value2要替换的字符串,value可以使用字符串形式,也可以使用正则表达式形式 /china/ig
i -> ignore 忽略大小写
g-> global 全局查找
match(value)用于查找匹配的字符串,返回一个数组 可以使用ig
search (value)用于查找满足条件的第一个字符的下标,如果找不到返回-1 只能使用i
内置对象,宿主对象,自定义对象
Math对象不需要使用new创建,可以直接使用。
PI 获取圆周率
abs() 取绝对值
floor()向下取整
ceil() 向上取整
round()四舍五入取整
max() 取一组数字最大值
min() 取一组数字的最小值
pow(x,y) 取x的y次幂
random() 取随机 范围>=0 <1
用于对日期和时间进行存储和计算
new Date('2018/11/11 10:20:30')
new Date(2018,10,11,10,20,30) //第二个参数月份的范围是0~11
new Date()存储当前的系统时间
new Date(1000*60*60*24) 存储的是距离计算机元年的毫秒数对应的日期时间
getFullYear/ 获取年
getMonth/ 获取月
getDate/ 获取日
getHours/ 获取小时
getMinutes/ 获取分钟
getSeconds/ 获取秒
getMilliseconds/ 获取毫秒
getDay(星期0~6)/ 获取星期几 从0到6
getTime(距离计算机元年的毫秒数) 例:1542339376789
toLocaleString() // 年-月-日 时:分:秒
tolocaleDateString() //年-月-日
tolocaleTimeString() //时:分:秒
setFullYear/setMonth/setDate/setHours/setMinutes/setSeconds/setMilliseconds/
setTime 距离计算机元年毫秒数,一旦使用后,年月日时分秒都会受到影响
例题:计算当前距离2018年圣诞节还有多少天多少小时多少分多少秒
//原理:计算两个Date对象的时间差—相差的毫秒
var d1=new Date();
var d2=new Date('2018/12/25')
//两个对象相减,返回的是两个对象相差的毫秒数。
var d3=d2-d1;
//把相差的时间转成秒
d3=Math.floor(d3/1000);
//获取相差的天数
var day=Math.floor(d3/(24*60*60));
//获取天数后相差的小时
//相差的描述和一天的描述取余,得到的结果是不满一天的秒数,把秒数转成小时
var hours=d3%(24*60*60);
hours=Math.floor(hours/(60*60));
//获取相差的分钟
//相差的秒数和1小时的秒数取余,得到的结果是不满一小时,把秒数转成分钟
var minutes=d3%(1*60*60);
minutes=Math.floor(minutes/(60));
//相差的秒钟 和60取余
var seconds=d3%60;
console.log('距离2018年圣诞节还有'+
day+'天'+
hours+'小时'+
minutes+'分钟'+
seconds+'秒'
);
例题:创建对象保存一个员工的入职时间’2018-11-16’,3年后到期要求到期时间,合同到期前一个月续签合同,假如续签时间是周末,提前到周五。提前一周来通知人事准备续签(提醒时间)
var workTime=new Date('2018/11/16');
//复制入职时间的对象作为到期时间
//到期时间,年份在当前的基础之上加3
var target=new Date(workTime);
target.setFullYear(target.getFullYear()+3);
//复制一个到期时间
var reworkTime=new Date(target);
//提前一个月:在当前月份基础上减1
reworkTime.setMonth(reworkTime.getMonth()-1);
//判断是否为周末 6 0,周六提前一天-1,周日提前-2
var day=reworkTime.getDay();
if (day==6){
//设置日期为当前的日期-1
reworkTime.setDate(reworkTime.getDate()-1)
}else if(day==0){
reworkTime.setDate(reworkTime.getDate()-2)
}
//提醒时间:复制续签时间
var remind=new Date(reworkTime);
//设置当前日期在原来基础减7
remind.setDate(remind.getDate()-7);
console.log('入职时间:'+
workTime.toLocaleDateString()
);
console.log('到期时间:'+
target.toLocaleDateString()
);
console.log('续签时间:'+
reworkTime.toLocaleDateString()
);
console.log('提醒时间:'+
remind.toLocaleDateString()
);
new Number(值) 创建对象
将一个数据转为Number对象,本质还是数字。
Number.MAX_VALUE 获取计算机能存储的最大值
Number.MIN_VALUE 获取计算机能存储的最小值
toFixed(n) 保留小数点后 n位
toString() 将数字转为字符串类型
数字+'' //隐式转为字符串类型
new Boolean(值) 创建布尔对象,本质上将数据转为布尔型
Boolean(值) 转为布尔型
!!值 隐式将数据转为布尔型
toString() 将布尔型数据转为字符串
null的作用:用于释放(销毁)一个引用类型的数据。
SyntaxError 语法错误,错误的使用了中文,缺少括号....程序不会执行
ReferenceError 引用错误,使用未声明的变量
TypeError 类型错误,错误的使用了数据类型,错误的使用了括号
RangeError 范围错误,参数的使用超出了范围
new Array(-1)
引用错误、类型错误、范围错误出现后,会影响后续代码的执行。
异常处理:
try{
尝试执行的代码,可能出现错误
}catch(err){
err:捕获的错误信息
处理错误的方案
}
ECMAScript6
使用let关键字声明的变量,只能在块级作用域下访问,不能被外部访问。
块级作用域:{ }、for、while、do-while都是块级作用域
是回调函数的另一种写法,和匿名函数不完全一致
sort( (a,b)=>{
return a-b;
} )
如果箭头函数的函数体中只有一行代码,并且以return形式,可以简化为
sort( (a,b)=>a-b )
ES6允许为形参设置默认值,如果没有传递实参,自动调用形参中的默认值
` 在此之间可以写任意形式的代码 ${变量} `