JS语言基础知识
JS
特点:
- 解释型语言,编译一行执行一行
- 弱类型语言
- 基于对象
- 跨平台
开发环境
浏览器端:
世界5大浏览器:谷歌、火狐、edge、Safari、欧朋
服务器端:
Node.js node 将文件拖拽
浏览器端:
创建xx.html和xx.js,将js文件嵌入到html中
语法规范:
区分大小写
每行代码结束的分号可以省略
分为单行注释(//)和多行注释(/* */)
变量与常量
声明变量:
使用var或者let声明变量。
变量的命名规则:
可以由字母、数字、下划线、美元符号组成,不能以数字开头,不能使用关键字
语义化(可读性)
变量的赋值:
变量声明后未赋值则为undefined(未定义)。
变量声明后可以被重新赋值,并且赋不同类型的值,这是弱类型语言的特点。
常量:
和变量一样用于存储数据的容器,声明后必须赋值,不允许重新赋值
const pi=3.14;
使用const声明常量.
- 注意!var,let,const的区别
var声明的变量存在变量提升,允许重复声明.
let,const存在块级作用域,任何情况下都不是全局的.
var,let允许重新赋值.
const声明后必须赋值,不允许重新赋值.
数据类型
分为原始类型和引用类型。
原始类型分为数值型、字符串型、布尔型、未定义型、空。
通常使用typeof检测数据类型。
数值型:
分为整型、浮点型。
整型
整型就是进制型,有10进制、8进制、16进制。
10进制
1 2 3 .... 7 8 9 10 11 ... 15 16
8进制
1 2 3 ... 7 10 11 12
16进制
1 2 3 ... 7 8 9 a ... f 10
8进制以0开头的数字,例如012。
16进制以0x开头的数字,af代表1015,不区分大小写。
浮点型
3141.5E-1
314.15
31.415E+1
3.1415E+2
var n4 = 3.1415E+2;//向右移动两位
var n5 = 3141.5E-1;//向左移动一位
var n6 = 314.15;
console.log(n4,n5,n6);//n4 = 314.15,n5 = 314.15,n6 = 314.15
字符串型:
被引号包含的数据,不区分单双引号。
查看任意一个字符的Unicode码。
//查看任意一个字符的Unicode码
console.log( 'abc'.charCodeAt() );
布尔型:
只有两个值,分别是true和false,代表真和假。
通常用于保存只有两个状态的数据,例如是否登录、是否在线... 一些运算符的结果也是布尔型。
未定义型:
只有一个值是undefined,代表一个空值,例如声明了变量未赋值为undefined。
空:
只有一个值是null,类型是object,常结合对象一起使用。
数据类型转换
分为隐式转换和强制转换。
隐式转换:
在运算过程中自动产生的数据转换。
(1)数字+字符串 数字转换为字符串。
1 + '2' // '12'
(2)数字+布尔型 布尔型转换数值 true -> 1 false -> 0。
2 + true //3
2 + false //2
(3)布尔型+字符串 布尔型转为字符串。
true + '5' //'true5'
//隐式转换
//1转换为了字符串1,然后执行拼接(+)
var n1 = 1 + '2';//'12'
var n2 = 2 + false;//2
var n3 = true + '5';//'true5'
加号(+)的作用:
执行数字之间的加法运算。
执行字符串之间的拼接。
NaN:Not a Number(不是一个数字)。
在将一个数据转换为数值型时候,没有成功得到一个数字就会返回NaN。
NaN和任意数字执行运算,结果还是NaN。
- 注意!
所有的隐式转换为数字都是会自动调用函数Number完成的。
强制转换:
(1)强制转换为数值型
Number()
Number('1') //1
Number(true) //1
Number(false) //0
Number(undefined) //NaN
Number(null) //0
Number('1a') //NaN
(2)强制转换为整型
parseInt()
强制将字符串和小数转为整型。
parseInt('3.94') //3
parseInt('6.18a') //6
parseInt('a6.18') //NaN
parseInt(5.9) //5
注意!undefined null true false都是返回NaN。
(3)强制转换为浮点型
parseFloat()
强制将字符串转换为浮点型。
parseFloat('3.14') //3.14
parseFloat('6.18a') //6.18
parseFloat('6a') //6
parseFloat('a6.18') //NaN
(4)数值和布尔型强制转字符串
toString()
var num = 5;
num.toString() //'5'
运算符
表达式:由数据本身或者由运算符连接的操作数据组成的形式称作表达式。
运算符分为算术运算符、比较运算符、逻辑运算符、位运算符、赋值运算符、三目运算符。
(1)算术运算符
+ - * / % ++ --
% 取余
++ 自增,在原来的基础之上加1。
var a1 = 2;
//让a1变量在原来的基础之上加1
//a1++;//后置
++a1; //前置
console.log(a1);
-- 自减,在原来的基础之上减1。
(2)比较运算符
> < >= <= ==(等于) !=(不等于) =(全等于) !(不全等于) 。
等于:只是比较两者的值是否相同,可能会发生隐式转换。
全等于:同时比较类型和值,都相同结果才是true,否则false。
不等于:比较值是否不相同。
不全等于:同时比较类型和值,有一个不等为true,否则false。
3>'10' 数字和字符串比较,字符串转为数值。
'3'>'10' 字符串比较,比较的是首个字符的Unicode码。
'3' -> 51 '1' -> 49
3>'10a' //false
3<'10a' //false
3=='10a' //false
- 注意!
NaN和任何值比较(> < >= <= == ===)结果都是false
NaN == NaN //false
(3)逻辑运算符
&& || !
&& 逻辑与,关联的两个条件都为true,结果是true,否则false
|| 逻辑或,关联的两个有一个为true,结果是true,否则false
! 逻辑非,取反
-
短路逻辑
逻辑与,如果第一个条件是false,就不再执行第二个条件
逻辑或,如果第一个条件是true,就不再执行第二个条件
var a = 3;
a > 1 && console.log(num);
a < 5 || console.log(num);
短路逻辑关注点在于是否会执行第二个表达式。
(4)位运算符
模拟计算机底层的运算,先把数据转为2进制,然后进行运算;当运算完以后再把结果转回成10进制。
1 2 3 4 5 6 7 8
1 10 11 100 101 110 111 1000
(5)赋值运算符
= += -= *= /= %= ...
运算赋值:先执行运算,再执行赋值。
(6)三目运算符
一目运算符:由一个运算符连接的一个操作数据或者表达式 ! ++ --
二目运算符:由一个运算符连接的两个操作数据或者表达式。
三目运算符:由两个运算符连接的三个操作数据或者表达式。
条件表达式 ? 表达式1 : 表达式2
如果条件表达式为true,执行表达式1
如果条件表达式为false,执行表达式2
//判断一个人是否为成年人
var age = 11;
var res = age >= 18 ? '成年人' : '未成年人';
浏览器端函数
alert() 弹出警示框。
prompt() 弹出提示框(输入框),需要使用变量保存用户输入的值,类型是字符串型,如果点击取消返回null。
- 程序 = 数据 + 算法
- 程序的执行方式:顺序执行、选择执行、循环执行。
流程控制
if语句
if(条件表达式){
语句块
}
//满30减20
var total = 28;
//判断总价是否满30
if(total >= 30){
//在原来基础之上减20
total -= 20;
}
console.log(total);
如果if后的语句块中只有一行代码,则大括号可以省略的
以下5种情况隐式转换为布尔型为false:0 NaN '' undefined null
//false: 0 NaN '' undefined null
//如果空字符串作为条件是false
//整体上的条件需要为true才会执行后边的语句
if(!''){
console.log('用户名不能为空');
}
if-else语句
if(条件表达式){
语句块1
}else{
语句块2
}
//判断一个人是否为成年人
var age = 11;
if(age >= 18){
console.log('成年人');
}else{
console.log('未成年人');
}
if-else嵌套
if(条件表达式1){
语句块1
}else if(条件表达式n){
语句块n
}else{
语句块n+1 //以上所有的条件都是false
}
假设从数据库中读取到了订单的状态码,根据订单的状态码打印对应的汉字状态
//1-等待付款 2-等待发货 3-运输中 4-已签收 5-已取消 其它-无法追踪
var status = null;
if(status === 1){
console.log('等待付款');
}else if(status === 2){
console.log('等待发货');
}else if(status === 3){
console.log('运输中');
}else if(status === 4){
console.log('已签收');
}else if(status === 5){
console.log('已取消');
}else{
console.log('无法追踪');
}
switch-case语句
是一种特殊的多项分支语句
switch(表达式){
case 值1: //如果表达式和case后的值相同,会执行对应的语句块
语句块1
break;
case 值n:
语句块n
break;
default:
语句块n+1
}
//根据星期的值打印对应的汉字状态
//星期的值(0~6)
var n = '2';
switch(n){
case 0:
console.log('星期日');
break;
case 1:
console.log('星期一');
break;
case 2: // 全等于
console.log('星期二');
break;
case 3:
console.log('星期三');
break;
default:
console.log('错误的星期');
}
表达式在和case后的值比较的时候,用的是全等于(===)。
- 注意
对比if-else和switch-case
if-else可以进行各种条件的比较,switch-case只能进行全等于的比较。
switch-case的代码结构更为清晰,执行效率更高。
循环
一遍又一遍执行相同或者相似的代码。
循环的两个要素:
循环条件: 控制循环的执行。
循环体: 要重复执行的代码。
while循环
while(循环条件){
循环体
}
//打印10~1之间所有的整数
//初始值
var i = 10;
while(i>=1){//循环条件
//循环体
console.log(i);
//增量
i--;
}
break
在循环体中使用,用于跳出循环,不再执行任何循环中的代码。
//当循环条件为true,计算10~20之间所有整数的乘积
//初始值
var i = 10;
var s = 1;//声明变量,用于保存乘积
while(true){
//i代表所有的整数
//console.log(i);
//把所有的整数乘以到s中,在原来基础之上乘积每个整数
s *= i; //1*10*11...*20
//当i为20的时候,跳出循环
if(i === 20){
break;
}
//增量
i++;
}
//当循环结束后,打印最终的结果
console.log(s);
do-while循环
do{
循环体
}while(循环条件);
//打印1~10之间所有的整数
//初始值
var i = 1;
do{
//循环体
console.log(i);
//增量
i++;
}while(i <= 10);//循环条件
for循环
for(初始值;循环条件;增量){
循环体
}
//循环打印1~10之间所有的整数
for(var i = 1;i <= 10;i++){
//循环体
console.log(i);
}
//练习:for循环打印50 45 40 35 30
for(var i = 50;i >= 30;i -= 5){
console.log(i);
}
break和continue
continue:跳过后续循环体代码,还会往后继续执行。
break:跳出循环,结束循环的执行。
//练习:打印1~100之间所有的整数,不包含能被3或者4整除的数字
for(var i = 1;i <= 100;i++){
//判断是否能被3或者4整除
if(i % 3 === 0 || i % 4 === 0){
continue;
}
console.log(i);
}
循环嵌套
在一个循环体的内部出现了另一个循环。
任意两个循环之间都可以相互嵌套。
//使用循环产生5个*,打印成一行
//*****
//外层循环:控制循环的行数
for(var j = 1;j <= 9;j++){
//内层循环:控制每一行循环的列数
for(var i = 1,str = '';i <= 9;i++){
//每循环一次,拼接一个*
str += '*';
}
//循环结束以后,打印拼接的这一行
console.log(str);
}
函数
Number()/parseInt()/parseFloat()/alert()/prompt()
函数分为系统函数和自定义函数。
函数:是一个功能体,需要提供若干个数据,返回处理的结果 —— 用于封装重复执行的代码。
创建函数
function 函数名称(){
函数体 //封装重复的代码
}
调用
函数名称()
每调用一次,就会执行一次函数体中的代码。
创建带有参数的函数
function 函数名称(参数列表){
函数体
}
调用
函数名称(参数列表)
创建函数时的参数称作形参,调用函数时的参数称作实参,实参会赋值给形参,实参的数量可以和形参的数量不匹配,如果形参未被赋值则为undefined.
//练习:创建函数getSum,在函数体中封装计算1~100之间所有整数的和并打印结果;调用多次
function getSum(){
//函数体
for(var i = 1,sum = 0;i <= 100;i++){
sum += i;
}
console.log(sum);
}
getSum();
getSum();
getSum();
创建带有返回值的函数
function 函数名称(参数列表){
函数体 return 值; //返回值,函数调用后返回的结果
}
调用
函数名称(参数列表) //得到函数的返回值
如果函数中没有写return或者return后没有任何值,则返回undefined
一旦执行return,就会跳出函数的执行
创建函数getStatus,传递订单的状态码,返回对应的中文状态
function getStatus(n){
switch(n){
case 1:
return '等待付款';
//break;
case 2:
return '等待发货';
//break;
case 3:
return '运输中';
//break;
case 4:
return '已签收';
//break;
case 5:
return '已取消';
//break;
default:
return '无法追踪';
}
}
//var res = getStatus(1);
//console.log(res);
switch-case
对比return和break
return用于函数中,跳出函数的执行.
break用于循环和switch-case,跳出循环或者switch-case语句.
//创建函数isPrime,传递任意一个数字,判断是否为素数,返回布尔型的值
function isPrime(n){
//循环产生1~n之间所有的整数,不包含1和n
for(var i = 2;i < n;i++){
//判断中间的每个数字i是否能被n整除
//如果有能被整除的数字,不是素数
if(n % i === 0){
return false
}
}
//循环结束后,表示没有出现能够被n整除的数字,说明是素数
return true;
}
//var res = isPrime(9);
//console.log(res);
//创建函数isRun,传递任意一个年份,判断是否为闰年,返回布尔型的值
function isRun(year){
/*
if(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0){
return true;
}
return false;
*/
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
var res = isRun(2021);
console.log(res);
变量的作用域和函数的作用域
变量的作用域:
全局变量:在全局作用域(函数以外)声明的变量就是全局变量,可以在任意的作用域下访问到。
局部变量:在函数作用域下声明的变量就是局部变量,只能在当前的作用域下访问到。
在函数内不加var声明的变量是全局变量,后期在严格模式下报错,不推荐。
//全局作用域
//全局变量
var a = '北京市城管';
function shi(){
//函数作用域
//局部变量
var b = '石景山城管';
//访问全局变量
console.log(a);
}
shi();
//在全局作用域访问局部变量
console.log(b);
function hai(){
//函数作用域
//局部变量
var c = '海淀城管';
}
//全局变量
var n1 = 6;
function fn(){
//函数内不加var声明的变量是全局变量
n = 2;
//访问到全局变量的同时,重新赋值
n1 = 8;
}
fn();
console.log(n);
console.log(n1);
function fun(){
var m1 = m2 = m3 = 3;
//m3 = 3 //全局变量
//m2 = m3 //全局变量
//var m1 = m2; //局部变量
}
fun();
console.log(m3);//3
console.log(m2);//3
console.log(m1);//错误:m1 is not defined
变量提升:程序执行前,会将var声明的变量提升到所在作用域的最前边,只是提升声明,赋值不提升。
//变量提升:程序执行前,会将var声明的变量提升到所在作用域的最前边,只是提升声明,赋值不提升
//var a;
console.log(a);//undefined
var a = 1;
console.log(a);//1
var c = 3;
function foo(){
//当前作用域下找不到c,会往上一级作用域
console.log(c);//3
//找到的全局变量c,重新赋值为5
c = 5;
console.log(c);//5
}
foo();
function bar(n){
//形参属于局部变量
}
bar(2);
//在全局作用域访问形参
//console.log(n);//报错
var m = 3;
function boo(m){
//m=undefined
//找的是形参m,不会找全局变量m
m = m + 7;
}
boo();
console.log(m);
函数的作用域:
全局函数:在全局作用域下创建的函数,可以在任意的作用域访问。
局部函数:在函数作用域下创建的函数,只能在当前的作用域访问。
函数提升:程序执行前,会将函数整体提升到所在作用域的最前边。
//创建函数
//全局函数
function fn(){
}
var a=0;
//----0级作用域-------
function fun1(){
//-------1级作用域----------
//var a=1;
//局部函数
function fun2(){
//------2级作用域---------
//var a=2;
console.log(a);
}
fun2();
}
//fun1();
//在全局调用局部函数
//fun2();//报错
//函数提升
foo();
function foo(){
console.log(4);
}
递归
是一个函数的内部调用自身这个函数,本身是一个死循环。
递归一直运行会产生内存泄漏,造成系统崩溃。
如何使用:
要有边界条件,结合着return使用。
JS属于单线程运行逻辑,无法充分利用CPU内核,递归对CPU消耗比较大,JS不适合深层次的递归嵌套。
//使用递归计算斐波那契数列第n项的值
//第n项的值 = 第n-1项的值 + 第n-2项的值
function fib(n){
//边界条件:当n为1或者2的时候,返回1
if(n === 1 || n === 2){
return 1;
}
return fib(n-1) + fib(n-2);
}
console.log( fib(70) );
//fib(4)+fib(3)
//fib(3)+fib(2)+fib(2)+fib(1)
//fib(2)+fib(1)+1+1+1
//1+1+1+1+1
//使用递归计算n~1之间所有整数和
function getSum(n){
//边界条件:当n为1的时候,返回1
if(n === 1){
return 1;
}
//规律:前n项的和 = n + 前n-1项的和
return n + getSum(n-1);
}
console.log( getSum(100) );
匿名函数
function(){ }
没有名称的函数
创建函数
函数声明
function fn(){
}
函数表达式
var fun=function(){
}
变量名称就是函数名称
调用 fun()
对比函数名称和函数名称()
函数名称():调用函数,得到函数的返回值;
函数名称:本质上就是一个变量,保存了一个函数。
对比函数声明和函数表达式创建函数的区别
函数声明存在函数提升,可以先写调用再写创建;
函数表达式只是变量声明提升,必须先写创建再写调用。
//使用函数表达式创建函数getSum,传递任意两个数字,返回两个数字之间所有整数的和。
//var getSum
var getSum = function(n1,n2){
//计算n1~n2之间所有整数的和
for(var i = n1,sum = 0;i <= n2;i++){
sum += i;
}
return sum;
}
//console.log( getSum(1,100) );
匿名函数自调用
目的是为了防止全局污染
(function(){
//函数作用域下,里边的变量都是局部变量
})();
//全局污染:全局变量出现造成的
//轮播图1
//匿名函数自调用
(function(){
var num = 2;
console.log(num);
})();
//轮播图2
(function(){
var num = 1;
console.log(num);
})();
//轮播图3
(function(a){
var num = 4;
console.log(num,a);
})(20);
回调函数
将函数作为参数来传递到另一个函数。
function tao(madai){
madai() //调用传递的回调函数
}
function dong(){
}
tao(dong) //dong是回调函数
tao(function(){ }) //匿名函数是回调函数
function tao(madai){
console.log('涛哥开始跑第一棒');
console.log('涛哥到达第一棒终点');
//madai=dong
//madai=function(){}
//传递的函数需要通过形参来接收,通过形参来调用
madai();//相当于dong() // (function(){})()
}
function dong(){
console.log('东哥开始跑第二棒');
console.log('东哥到达第二棒终点');
}
//把函数dong作为实参传递,dong就是回调函数
tao(dong);
//把匿名函数作为实参传递
tao(function(){
console.log('陌生人从麻袋中跑了出来');
});
系统函数
isNaN() 判断一个值是否为NaN,会隐式转换为数值型,
是NaN -> true 不是NaN -> false
isFinite() 判断一个值是否为有限值,只有Infinity是无限值,其它都是有限值
2/0 -> Infinity
eval() 执行字符串表达式
对象
是一组属性和方法的集合
一部手机,属性有颜色、品牌、CPU、内存... 方法有打电话、发短信、玩游戏、看视频、办公...
涛哥,属性有发色、身高、体重... 方法有摊煎饼、养兔子、跑接力赛...
万物皆对象
JS中的对象
自定义对象:用户自己创建的对象。
内置对象:JS提供的对象。
宿主对象:根据不同的执行环境划分。
自定义对象创建方式
对象字面量。
内置构造函数。
自定义构造函数。
对象字面量
{ 属性名1: 属性值1, 属性名2: 属性值2.... }。
属性名的引号可以省略,如果含有特殊字符必须添加。
//练习:创建一个商品对象,包含的属性有编号,标题,价格,是否在售
var laptop = {
lid: 1,
title: '小米Air',
price: 4199,
'is-onsale': '否'
};
//console.log(laptop);
访问属性
对象.属性名
对象['属性名']
如果访问没有的属性,则返回undefined
//创建一个图书对象,包含的属性有编号,书名、作者、价格;修改图书的价格,添加图书的出版社,出版时间;最后打印对象
var book = {
bid: 1001,
bname: '兔子的产后护理',
author: '尼古拉斯.涛',
price: 599
};
book.price = 799;
book.publish = '非洲人民出版社';
book['pubtime'] = '2021年1月1日'
console.log(book);
内置构造函数
new Object() 创建一个空对象,需要单独的添加每个属性
//创建一个汽车对象,包含有汽车的品牌,颜色,长度,宽度
var car = new Object();
car.brand = '特斯拉';
car.color = '白色';
car.len = '4711mm';
car.width = '1823mm';
//console.log(car);
遍历属性
for(var k in 对象){
k代表每个属性名
对象[k] 代表属性名对应的属性值
}
//使用对象字面量创建一个学生对象,包含有学号,姓名,性别,分数;遍历对象得到每个属性
var student = {
sid: 1,
name: 'dong',
sex: '男',
score: 82
};
for(var k in student){
console.log(k,student[k]);
}
检测属性是否存在
对象.属性名 === undefined 存在 -> false 不存在 -> true
对象.hasOwnProperty('属性名') 存在 -> true 不存在 -> false
'属性名' in 对象 存在 -> true 不存在 -> false
//创建对象保存一条商品的数据,包含有编号,标题,价格属性,如果价格属性存在,在原来的基础之上打九折,如果产地属性不存在则添加该属性,最后打印对象
var laptop = {
lid: 9,
title: '小米Air',
price: 4199
};
if(laptop.hasOwnProperty('price')){
//打九折
laptop.price *= 0.9;
}
if(laptop.madeIn === undefined){
laptop.madeIn = '中国';
}
console.log(laptop);
对象中的方法
方法对应的是一个函数.
//创建一个圆的对象,包含的属性有半径、圆周率,添加两个方法,分别是计算面积和周长,并将计算的结果返回;最后调用两个方法
function fn(){
//计算面积
return this.pi * this.r * this.r;
}
var circle = {
r: 4,
pi: 3.14,
area: fn,
len: function(){
//计算周长
return 2 * this.pi * this.r;
}
};
console.log(circle);
console.log( circle.area() );
console.log( circle.len() );
数据的存储
原始类型,将数据直接存储在栈内存;
引用类型,将数据存储在堆内存中,然后自动生成一个16进制地址,然后将地址保存在栈内存
null:表示空地址,没有指向任何堆内存数据
引用类型的数据如果不被任何的地址所指向就会自动销毁,直接赋值为null,就可以销毁引用类型的数据。
数组
就是一组数据的集合。
字面量创建数组
[ 元素1, 元素2 ... ]
访问数组元素
数组[下标]
下标:自动为每个元素添加的编号,从开始的整数
如果访问不存在的元素,则结果为undefined
数组的长度
数组.length 获取数组元素的数量
在数组末尾添加元素 数组[ 数组.length ] = 值
//创建数组
//字面量
var ename = ['涛哥','东哥',20,true,null,{}];
//console.log(ename);
//创建数组,包含一组成绩;创建数组,包含一组商品的标题;
var score = [72,85,93,66];
//console.log(score,typeof score);
var title = [
'华为',
'小米Air',
'戴尔燃'
];
//下标:自动为每个元素添加的编号,从0开始的整数
//console.log( title[3] );
title[0] = '荣耀';
title[3] = '联想';
title[6] = '苹果';
//console.log(title);
//创建数组包含有多个国家的名称,修改其中的一个元素,在末尾添加两个元素
var country = ['瓦坎达','日本','印度','土耳其'];
//country[2] = '印尼';
//country[4] = '美国';
//country[5] = '英国';
//用长度作为下标
country[ country.length ] = '美国';
country[ country.length ] = '英国';
country[ country.length ] = '德国';
//获取数组长度
//console.log( country.length );
//console.log(country);
//创建一个空数组,添加若干个汽车的品牌名称
var car = [];
car[ car.length ] = '奥迪';
car[ car.length ] = '奥拓';
car[ car.length ] = '特斯拉';
console.log(car);
内置构造函数创建数组
new Array(元素1,元素2,...)
new Array(4) 创建数组,初始化长度为4,可以添加更多个元素
//创建数组,包含多个城市的名称;
var city = new Array('北京','广州','杭州');
console.log(city);
//创建数组,初始化长度为5,添加5张图片的名称
var city = new Array(5);
city[0] = 'img/1.png';
city[1] = 'img/2.png';
city[2] = 'img/3.png';
city[3] = 'img/4.png';
city[4] = 'img/5.png';
console.log(city);
数组的分类
索引数组:以0及以上的整数作为下标
关联数组:以字符串作为下标,只能单独的添加元素
关联数组不能使用length属性获取数组的长度
遍历数组元素
依次访问数组中的每个元素
for-in
for(var k in 数组){
k 代表下标
数组[k] 下标对应的元素
}
或者是循环 —— 推荐用法
for(var i=0;i < 数组的长度;i++){
i 代表下标
数组[i] 下标对应的元素
}
//创建数组,包含一组成绩,遍历数组元素,计算出总分和平均分
var arr = [82,93,77,85,66,55];
for(var i = 0,sum = 0;i < arr.length;i++){
//console.log(i,arr[i]);
//计算总分
sum += arr[i];
}
console.log(sum, sum/arr.length);
API
应用程序编程接口:JS中预定义的函数或者对象下的方法。例如:
toString() 将数组转为字符串。
join('-') 将数组转为字符串,默认用逗号分割元素,可以指定分割符号。
concat(arr2,arr3...) 拼接多个数组,arr2,arr3代表要拼接的数组。
reverse() 翻转数组元素。
sort() 对数组进行排序,默认是按照首个字符的Unicode码从小到大排序。
sort( function(a,b){
return a-b;//按照数字从小到大排序
//return b-a; //按照数字从大到小排序
} )
slice(start,end) 截取数组元素,start开始的下标,end结束的下标,不包含end,如果end为空截取到最后,如果下标是负数表示倒数;返回截取到的元素,格式为数组。
splice(start, count, v1,v2) 删除数组元素,start开始的下标,count删除的数量,count为空删除到最后,下标为负数表示倒数,v1,v2表示删除后补充的元素,返回删除后的元素,格式为数组;原数组会发生变化。
push() 在数组的末尾添加一个或者多个元素,返回数组的长度,原数组会发生变化 。
pop() 删除数组末尾的一个元素,返回删除的元素,原数组发生变化。
unshift() 在数组的开头添加一个或者多个元素,返回数组的长度,原数组会发生变化。
shift() 删除数组开头的一个元素,返回删除的元素,原数组发生变化。
indexOf() 判断数组中是否含有某个元素,存在返回下标,如果不存在返回-1。
API的学习主要是在于学会作用以及需要的参数、返回值。
数组API还需要查看原数组是否会发生变化。
二维数组
对数据进行二次分类
[ [ ], [ ], [ ] ]
访问
数组[下标][下标]
//省份
var arr1 = ['山东','广东','浙江'];
//城市
var arr2 = ['济南','青岛','烟台','威海','深圳','广州','珠海','惠州','东莞','杭州','宁波','绍兴'];
//二维数组
var arr3 = [
['济南','青岛','烟台','威海'],
['深圳','广州','珠海','惠州','东莞'],
['杭州','宁波','绍兴']
];
console.log(arr3[2][2]);
字符串对象
包装对象:目的是为了让原始类型的数据像引用类型的数据一样,具有属性和方法,一共三种包装对象,字符串对象,数值对象,布尔对象
new String() 将数据强制转换为字符串,返回对象
String() 将数据强制转换为字符串,返回字符串
转义字符
转换字符本身的意义
' 将具有特殊意义单引号转为普通引号
\n 将普通的字符n转义为换行符
\t 将普通的字符t转义为制表符(tab键效果)
API
length 获取字符串的长度
charAt() 获取下标对应的字符,也可以使用数组格式 字符串[下标]
indexOf() 查找字符串,返回满足条件的第一个的下标,找不到返回-1
lastIndexOf() 查找字符串,返回满足条件的最后一个的下标,找不到返回-1
toUpperCase() 将英文字母转大写
toLowerCase() 将英文字母转小写
slice(start, end) 截取字符串,start开始的下标,end结束的下标,end为空截取到最后,下标为负数表示倒数,返回截取到的字符串
substr(start, count) 截取字符串,start开始的下标,count截取的长度,count为空截取到最后,下标为负数表示倒数,返回截取到的字符串
split(str) 将字符串转为数组,按照指定的字符str分割
Math对象
不需要创建,可以直接使用API
PI 获取圆周率
abs() 求绝对值
ceil() 向上取整
floor() 向下取整
round() 四舍五入取整
max() 获取一组数字最大值
min() 获取一组数字最小值
pow(x,y) 计算x的y次方
random() 获取随机,范围 0~1 >=0 <1
Date对象
用于对日期时间的存储和计算
创建
new Date('2021/6/17 10:20:30')
new Date(2021,5,17,10,20,30) 月份范围0~11 代表1~12月
new Date(1683036000000) 存储距离计算机元年的毫秒数对应的日期时间
new Date() 存储当前操作系统的时间
获取
getFullYear/getMonth/getDate
月份范围0~11 对应1~12月
getHours/getMinutes/getSeconds/getMilliseconds(毫秒)
getTime 获取距离计算机元年毫秒数
getDay 获取星期 范围0~6 对应星期日~星期六
转为本地字符串格式
存在兼容性问题,用于测试
toLocaleString() 获取完整的
toLocaleDateString() 获取日期部分
toLocaleTimeString() 获取时间部分
修改
setFullYear()/setMonth()/setDate()
setHours()/setMinutes()/setSeconds()/setMilliseconds()
setTime() 设置距离计算机元年毫秒会,产生具体的日期时间
//创建对象保存当前操作系统的日期时间,修改为3天后,修改为7个小时前。
var d1 = new Date();
//把d1对象拷贝
var d2 = new Date(d1);
//修改为3天后:在当前基础上加3,再把结果设置为日期
d1.setDate( d1.getDate()+3 );
//7小时前
d1.setHours( d1.getHours()-7 );
console.log( d1.toLocaleString() );
console.log( d2.toLocaleString() );
Number对象
new Number() 将数据转为数值型,返回对象
Number() 将数据转为数值型,返回数值
toFixed(n) 强制保留小数点后n位
toString(n) 强制转为字符串,可以通过n设置进制
var n = 2 * 3.14 * 5;
//保留小数点后n位
console.log( n.toFixed(1) );
var total = 4199.55 + 5399*2 + 7199.33;
console.log(total.toFixed(2));
var num = 12;
//转为字符串
var str = num.toString(8);
console.log( str,typeof str );
Boolean对象
new Boolean() 将数据转为布尔型,返回对象
Boolean() 将数据转为布尔型,返回布尔型数据
var b1 = true;//字面量
//false: 0 NaN '' undefined null
var b2 = new Boolean(0);
var b3 = Boolean(5);
//console.log(b2,typeof b2);
//console.log(b3);
//{} []
//console.log( Boolean([]) );
//隐式转换为布尔型
console.log( !!{} );
错误处理
常见的错误
语法错误(SyntaxError):出现了中文符号,缺少括号等
引用错误(ReferenceError):使用了未声明的变量
类型错误(TypeError):函数或者对象下的方法找不到
自定义错误:程序员自己指定的错误
throw 错误内容
//类型错误
fn();
var fn = function(){
console.log(3);
}
var arr = [1,2,3];
arr.revese();
var age = 75;
if(age > 60 || age < 18){
//自定义错误
throw '非法的年龄';
}
错误处理
try{
尝试执行,可能出现错误
}catch(err){
捕获错误,一旦try中出现错误才会执行
将错误放入到err中
进行错误处理
}
//错误处理:出现错误不影响后边代码执行
var age = 75;
//尝试执行,可能会产生错误,出现错误不会再影响后边代码执行
try{
if(age > 60 || age < 18){
//自定义错误
throw '非法的年龄';
}
}catch(err){
//捕获错误,一旦try中出现错误才会执行
//err会报错错误信息
console.log(err);
//解决错误
age = 20;
}
console.log(age);
console.log(2);
ES6
ECMAScript ES
ES6是JS的第6版标准规范
ES7 ES8
ES2015 ES2016 ... ES2021
块级作用域
let声明变量不存在变量的提升,不允许重复声明.
let声明的变量不是全局变量.
大括号之间的语句块就是块级作用域,例如:if、else、for、while...
块级作用域下let和const声明的变量和常量是局部的.
//计算1~100之间所有整数的和,变量使用let声明
let sum = 0;
for(let i = 1;i <= 100;i++){
sum += i;
}
console.log(sum);
参数的默认值
function fn(a,b,c=0){
b = b || 0; //es6之前的默认值的方式
}
fn(5000)
//参数的默认值
function fn(a,b,c=0){
//es6之前写法
b = b || 0;
console.log(a + b + c);
}
fn(5000,4000,1000);
fn(5000,4000);
fn(5000);
箭头函数
简化了匿名函数的写法,不等价匿名函数
()=>{ }
sort( (a,b)=>{
return a-b;
} )
如果箭头函数的函数体中只有一行代码并且是return形式,可以简化为
sort( (a,b)=>a-b )
//使用箭头函数创建函数,传递任意三个数字,返回平均数。
let fn = (a,b,c)=>{
return (a+b+c)/3;
}
//简化形式:
let fn = (a,b,c)=>(a+b+c)/3;
//console.log(fn(1,2,3));
模板字符串
模板字符串 ${ JS表达式 }
解决了字符串的拼接问题
//创建对象保存一条员工的数据,包含属性姓名、性别(1/0)、工资、部门名称,最后打印以下格式
let emp = {
name: '涛哥',
sex: 1,
salary: 18000,
dname: '研发部'
};
console.log(`
姓名:${emp.name}
性别:${emp.sex ? '男' : '女'}
工资:${emp.salary.toFixed(2)}元
部门:${emp.dname}
`);

浙公网安备 33010602011771号