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进制地址,然后将地址保存在栈内存

img

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}
`);
posted @ 2021-06-20 20:47  趣多多奥利奥  阅读(173)  评论(0)    收藏  举报