javascript
- 是一种编程语言
javascript语言的组成
- ECMAScript
确定js语言的语法规范 一些特定的可以被计算机识别的代码) - DOM
文档对象模型
js动态操作网页内容 一套操作页面元素的API
通过DOM提供的API对文档树(HTML)进行节点操作 - BOM
浏览器对象模型
js动态操作浏览器窗口 一套操作浏览器功能的API
通过BOM可以操作浏览器窗口
应用场景
- 网页特效
- 游戏开发(通过cocos2d.js)
- 服务端开发(通过node.js)
- 命令行工具(通过node.js)
- 桌面程序(Electron)
- App(Cordova)
- 控制硬件(物联网Ruff)
凡是能用js实现的功能 最终都会用js来实现
js三种书写位置
- 行内式
写在标签内部
<div onclick="alert('我是行内写法')"></div>
- 内嵌式
写在script标签中
script标签可以写在head标签中 也可以写在body标签中
<script>
alert('我是内嵌写法')
</script>
- 外联式
写在js文件中
要用script标签的src属性导入
<script src='1.js'></script>
注意
如果script标签没有写src属性 是内联写法 js代码要写在标签里面
如果script标签写了src属性 是外联写法 js代码写在js文件中 此时script标签里面的代码无效
js代码注释
-
单行注释
//
注释内容只能是一行 -
对行注释
/**/
注释内容可以使多行
单行注释快捷键 ctrl + /
多行注释快捷键 ctrl + shift + /
js常用五句话
- 主要用于调试以及浏览器的简单交互
alert('弹出一个提示框');
console.log('在控制台输出');
prompt('弹出一个输入框');//得到的数据是字符串类型
confirm('弹出一个确认框');
document.write('动态给页面添加内容')
注意
console.log()是给程序员自己看的 不是给用户看的
document.write()可能会覆盖网页原本的内容
计算机工作原理
-
计算机组成
-
软件(安装在操作系统上 操作系统的底层又运行在硬件当中)
应用软件: 浏览器 qq 微信 webstorm…
系统软件: Windows Linux iOS… -
硬件
三大件: CPU 内存 硬盘
输入设备 鼠标 键盘 摄像头…
输出设备 显示器 打印机 投影机… -
代码进行的原理
-
代码在运行时 计算机主要做两件事
1.识别并实现语法
2.处理数据(计算和存储)
数据类型与直接量
-
直接量(字面量)
js可以直接拿来使用的数据
这里的数据是指符合数据类型的数据 -
数据类型
代码在运行的时候 会产生各种不同的数据 不同的数据 CPU处理与存储的方式是不一样的 所以 需要对数据进行数据类型的分类
字符串类型String
用于显示网页文本
一切以单引号或双引号引起来的内容 都是字符串类型
数值类型Number
用于数学计算
一切数学中的数字
- 数字的极值(了解)
console.log ( Number.MAX_VALUE );//1.7976931348623157e+308 无限接近于正无穷的数
console.log ( Number.MIN_VALUE );//5e-324 无限接近于0的正数
console.log (Infinity );//正无穷
console.log (- Infinity );//负无穷
布尔类型Boolean
表示事物的对立面
只有两个值 true真 false假
注意
谷歌控制台小技巧
字符串显示黑色 数字显示蓝色
typeof 检测数据所属的数据类型
- 两种语法
typeof(数据)
typeof 数据
typeof结果会得到数据所对应类型的
字符串
可以检测除null和数组之外的数据类型
console.log ( typeof 123 );//'number'
console.log ( typeof( 123 ) );//'number'
console.log ( typeof "123" );//'string'
console.log ( typeof true );//'boolean'
function fn(){}
console.log(typeof fn);//function
var a ;
console.log(typeof a);//undefined
var nu = null;
console.log(typeof nu);//object
var arr = [1,2,3];
console.log(typeof arr);//object
数组数据类型检测
Array.isArray(数据)
- 检测数据是否是数据 是数组返回true 不是数组返回false
var arr = [1,2,3];
console.log(Array.isArray(arr));//true
数据 instanceof Array
- 检测数据是否是数据 是数组返回true 不是数组返回false
var arr = [1,2,3];
console.log(arr instanceof Array);//true
万能的数据类型检测
Object.prototype.toString.call(数据)
- 可以检测所有的数据类型
var arr = [1,2,3];
console.log(Object.prototype.toString.call(arr));//[Object Array]
var nu = null;
console.log(Object.prototype.toString.call(nu));//[Object Null]
变量
- var (variable)关键字
内存中用来保存数据的一块空间 - 用于声明变量
用于在内存中存储数据
var num;//声明变量
num = 10;//赋值
console.log(num);//取值
注意
=号在js中是赋值运算符
作用是将等号右边的数据存入左边的变量对应的空间中
注意 不要把变量与字符串搞混淆
console.log('num');//打印的是num字符串
console.log(num);//打印num变量中存储的数据
-
变量的初始化
var num = 10;
-
变量的批量声明(同时声明多个变量)
var a,b,c;
-
变量的批量声明赋值
var a=10,b=10,c=10;
-
变量的重新声明(会覆盖已经存在的变量)
var num = 20;
-
变量的重新赋值(先销毁旧值 然后存入新值)
num = 10;
-
变量的值是另一个变量的值
-
是将变量中的数据复制一份给另一个变量
var a = 10;
//将a变量中的值复制一份给变量b
var b = a;
- 交换两个变量的值
var n1 = 10;
var n2 = 20;
var temp = n1;
n1 = n2;
n2 = temp;
console.log(n1);
console.log(n2);
- 不适用临时变量 交换两个变量的值
var a = 10;
var b = 20;
a = b - a;//b=20 a=10
b = b - a;//b= 10 a=10
a = a + b;//a = 20 b=10
console.log(a);
console.log(b);
变量的命名规则与规范
规则
必须遵守 不遵守程序会报错
变量名由字母 数字 下划线_ $符号组成 不能以数字开头
不能以js关键字和保留字作为变量名
规范
所有程序员需要遵守的代码习惯
命名要有意义 一般用英语名词
使用驼峰命名法 第一个英语单词首字母小写 后面每个单词首字母大写 如fontSize
js中的+号的两个作用
字符串连接符
- 把加号两边的数据连接成一个新的字符串
- 加号两边只要有一边是字符串 会拼接成字符串
console.log(100+'100');//'100100'
数学加号
- 两边都要是数字
console.log(1+1);//2
算术运算符与算术表达式
- 算术运算符
+ - * / %
- 运算符只是一种运算符的符号 单独存在没有意义 通常与数字在一起组成式子 也就是表达式
- 表达式一定有结果 要么直接打印出结果 要么存入变量中
console.log(1+1);//2
var a = 1+1;
console.log(a);//2
//%取模
console.log(10%3);//1
注意
除法中 0不能作为除数 如果一个数字除以0 会得到Infinity
如果一个除法的结果是无限循环小数 js只会保留小数点后的15-17位 对开发没有影响 可以忽略
- 复合算术运算符
+=
-=
*=
/=
%=
var num =10;
num = num % 3;
//等价于
var num = 10;
num %= 3
自增自减运算符
自增运算符++
- 自增表达式 由自增运算符组成的式子
num++
- 变量自身+1
自减运算符--
-
自减表达式 由自减运算符组成的式子
num--
-
变量自身-1
-
前自增与后自增
++num
num++
相同点:无论是前自增还是后自增 对于变量自身而已没有区别 都是自身+1
不同点 表达式结果不同
//后自增
var num =10;
num++;
console.log(num);//11
//先赋值 后自增
//将变量的值赋值给表达式的结果 再变量自身+1
var res = num++;
console.log(res);//11
//前自增
var num =10;
++num;
console.log(num);//11
//先自增 后赋值
//将变量自身+1 在将变量的值赋值给表达式的结果
var res = ++num;
console.log(res);//12
- 测试题1
var a = 1;
var b = a++ +a++;
//b=1+ a=2
//b=1+2=3 a=3
console.log(a);//3
console.log(b);//3
- 测试题2
var c = 10;
var d = c++ + ++c -c--;
//d=10+ c=11
//d=10+12- c=12
//d=10+12-12 c=11
console.log(c);//11
console.log(d);//10
关系表达式与关系运算符
关系运算符
- 比较两个数字之间的关系(判断某种条件是否成立)
>
>=
<
<=
==
!=
===
!==
关系表达式
- 由关系运算符组成的式子
- 结果一定是布尔类型 true关系成立 false关系不成立
console.log(10<2);//false
console.log(1=='1');//true
console.log(1==='1');//false
==
相等与===
全等的区别
==
相等运算符 只比较数据的值 不比较数据的类型
===
全等运算符 先比较数据的值 后比较数据的类型
注意
区别于=号
=号
是赋值运算符
将等号右边的数据存入左边的变量中
逻辑运算符与逻辑表达式
逻辑运算符
- 计算多个条件之间的关系
&&逻辑与 一假则假
||逻辑或 一真则真
!逻辑非 取反 true变false false变true
逻辑运算符的短路运算
- 如果左边的式子能够决定逻辑表达式的结果 那么右边的式子不会执行
- 逻辑与 一假则假
找假
如果左边的式子能够转换为false 就无条件返回左边式子的值 反之无条件返回右边式子的值 - 逻辑或 一真则真
找真
如果左边的式子能够转换为true 就无条件返回左边式子的值 反之无条件返回右边式子的值 - 逻辑非
没有短路运算
因为逻辑非只有一个式子
var num = 10;
var res = 1>2 && num++;
console.log(res);//false 一假则假 &&后面的式子不会执行
console.log(num);//10
var res = 1 || null;
console.log(res);//1
var res = undefined || null;//一真则真
console.log(res);//null
- 逻辑表达式的结果不一定是布尔类型 ! ! ! ! !
var num =10 && 20;
console.log(num);//20
逻辑表达式
- 由逻辑运算符组成的式子
console.log(20>10 && 20<5);//false
console.log(20>10 || 20<5);//true
console.log(!true);//false
运算符的优先级(了解)
- 不同的运算符运算的顺序不一样
- 小括号()
作用 提升优先级 - 自增自减运算符
- 算数运算符
- 关系运算符
- 逻辑运算符
- 赋值运算符
Math高级数学函数
Math语法 | 描述 |
---|---|
Math.PI | 圆周率 |
Math.abs() | 绝对值(返回一个数字距离坐标原点的距离) |
Math.ceil() | 天花板函数(向上取整) |
Math.floor() | 地板函数(向下取整) |
Math.max() | 取一组数字的最大值 |
Math.mix() | 取一组数字的最小值 |
Math.round() | 四舍五入 |
Math.pow(x,y) | 幂运算 (求x的y次方) |
Math.random() | 随机数(生成0-1之间的小数) |
console.log(Math.PI);//3.141592653589793
console.log(Math.abs(-2));//2
console.log(Math.ceil(1.2));//2
console.log(Math.floor(1.2));//1
console.log(Math.max(10,20,30));//30
console.log(Math.min(10,20,30));//10
console.log(Math.round(10.5));//11
console.log(Math.pow(2,3));//8
console.log(Math.random());//生成0-1之间的随机小数
console.log(Math.random()*100);//生成0-100之间的随机小数
console.log(Math.ceil(Math.random()*100));//生成1-100之间的随机整数 需要向上取整
console.log(Math.floor(Math.random()*100));//生成0-100之间的随机整数 需要向下取整
数据类型
-
基本数据类型
number
string
boolean
null
undefined -
复杂数据类型
Array
Object
Function -
undefined
只有一个值 就是undefined
未定义
如果变量只声明 未赋值 默认值就是undefined -
null
只有一个值 就是null
空值
必须手动设置 变量在任何时候自己的值都不会是null
如果使用typeof检测null 结果会得到object 无法用typeof检测null
如果要检测 可以使用Object.prototype.toString.call(null);
来检测 结果是[Object Null]
undefined与null的区别(重点)
undefined与null的数据类型不同 但是值的比较的时候是相同的
console.log(undefined==null);//true 它们的值都是空
console.log(undefined===null);//false 它们的值相等 但是数据类型不同
NaN与isNaN
NaN (not a number)
是number数值类型中的一个特殊的值
表示数学错误的计算结果
如果数学计算结果不是一个数字 就会得到NaN
注意
NaN与任何数字计算的结果都是NaN
NaN与任何数字都不等 包括它自身
console.log('字符串'-20);//NaN
console.log(NaN+1);//NaN
console.log(NaN==0);//false
console.log(NaN==NaN);//false
console.log(typeof NaN);//'number'
检测一个数据是不是NaN
- 语法 isNaN(数据)
- 如果结果是数字 返回false 结果不是数字 返回true
console.log(isNaN(NaN));//true
console.log(isNaN('字符串'-1));//true
console.log(isNaN(10-1));//false
显式类型转换
- 程序员主动调用关键字来转换
其他数据类型转number
1.string字符串类型转number
- .
parentInt(数据)
转整数
工作原理: 从左往右逐个解析字符 遇到非数字字符会结束解析 并返回已经解析好的整数 如果第一个字符串就是非数字字符 直接返回NaN parentFloat(数据)
转浮点数
工作原理: 从左往右逐个解析字符 可以识别第一个小数点 后面再遇到非数字字符会结束解析 并返回已经解析好的数字 如果第一个字符串就是非数字字符 直接返回NaN
2.其他数据类型转number
Number(数据)
工作原理: 可以解析整数与小数 将整个数据进行解析 只要有一个非数字字符就会返回NaN- 常见的是布尔类型转数值类型 会得到0或1
true转1 false转0 - undefined转数值类型 会得到NaN
- null转数值类型 会得到0
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0
console.log(Number(''));//0
一般数字字符串转数字使用parseInt和parseFloat 其他数据类型转数字用Number()
其他数据类型转string
String(数据)
可以识别undefined与null变量名.toString()
不能识别undefined与null
其他数据类型转boolean
Boolean(数据)
布尔类型只有两个值
false: 八种情况会得到false
0 -0 NaN '' undefined null false document.all()
true: 除开得到false的八种情况之外的一切数据
隐式类型转换
- 当运算符两边的数据类型不一样 编译器会偷偷帮我们转成一致在进行计算
转number的情况
- 算数运算符(
+ - * / %
) - 关系运算符(
> >= < <= == != === !==
) - 自增自减(
--
++
)
//编译器帮我们将'10'转成Number('10')再去运算
console.log('10'-2);//8
//编译器帮我们将'字符串'转成Number('字符串')再去运算
//Number('字符串')是整个数据解析 遇到非数字字符直接返回NaN
//NaN与任何数字的运算结果都是NaN
console.log('字符串'-2);//NaN
转string的情况
+
字符串连接符
注意
+号有两个作用 一个是算术运算符 一个是字符串连接符
只要+号两边有一边是字符串 那么+号就是字符串连接符
否则+号就是算术运算符
//只要加号有一边是字符串 那么加号就是字符串连接符
//编译器会将10转成String(10) 再去拼接
console.log(10+'10');//'1010'
//+号两边没有字符串 就是算术运算符 那么编译器会将true转成Number(true) true转数值类型是1 false转数值类型是0
console.log(1+true);//2
console.log('1'+true);//'1true'
转boolean的情况
- 逻辑非!
取反 true变false false变true
//编译器遇到逻辑非 会将数据转成Boolean(0) 结果是false !取反 结果是true
console.log(!0);//true
//编译器遇到逻辑非 会讲数据转成Boolean(1) 结果是true !取反结果是false !再取反 结果是true
console.log(!!1);//true
程序流程控制
顺序结构(默认)
- 代码从上往下顺序依次执行
分支结构
if分支结构
适用于一种条件判断
代码根据条件执行
- 语法:
if(条件){ 条件成立时执行大括号里面的代码 }
注意
if小括号的结果一定是布尔类型
if中小括号里面的代码
1.常用的是关系表达式
2.直接写布尔类型的值
3.写其他的值 编译器会帮我们转布尔类型Boolean(数据)再来判断是否成立
if-else分支结构
-
适用于两种互斥条件
-
互斥条件 两个条件一定会满足一个 (不会同时满足 也不会同时不满足)
-
大括号中的代码 一定会执行一个( 不会同时执行 也不会同时不执行)
-
语法:
if(条件){
条件成立时执行的代码
}else{
条件不成立时执行的代码
}
- if-else优点
两个互斥条件 只需要判断一次
if-else if-else结构
- 适用于多种条件判断
- 必须要以if开头 中间else if可以是多个 结尾else可以省略 一般不会省略 会导致逻辑漏洞
- 所有大括号中的代码最多只会执行一个
- 语法:
if(条件1){
条件1成立时执行的代码
}else if(条件2){
条件2成立时执行的代码
}else{
以上条件都不成立时执行else里面的代码
}
switch-case分支结构
-
适用于固定值匹配
匹配: 全等=== -
语法:
switch(匹配值){
case 值1:
匹配值===值1时需要执行的代码;
break;
case 值2:
匹配值===值2时需要执行的代码;
break;
default:
匹配值与case后面的值都不全等 需要执行的代码;
break;
}
- break关键字作用
结束switch-case语句
防止穿透
注意
匹配值与case后面的值一定要是全等的关系
default代码块可以写在任何位置 但是一般写在最后面
如果不写break 则会发生穿透现象(代码无条件从上一个case执行到下一个case)
写break的作用 阻止穿透现象
如果多个值需要执行的代码相同 可以合理使用穿透现象
三元运算符与三元表达式
三元运算符
- 运算符根据操作的数的多少分为一元运算符 二元运算符 三元运算符
一元运算符++ --
只能操作一个数
二元运算符 算数运算符 关系运算符 操作两个数
三元运算符 可以操作三个数
三元表达式
- 由三个运算符组成的式子
- 语法:
表达式?代码1:代码2
- 如果表达式成立 则执行代码1 否则执行代码2
- 如果代码1和代码2有结果 那么三元表达式的结果就是代码1和代码2的值
注意
三元表达式做的事与if-else一样 只是代码更简洁
//如果代码1和代码2有结果 那么三元表达式的结果就是代码1和代码2的值
var res = 1>10?10:20;
console.log(res);//20
循环结构
- 循环中人为结束循环使用break
while循环结构
- 适用于循环次数不固定的场景
- 代码重复执行
- 先判断条件 后执行循环体
- 特点 如果循环条件不成立 循环体可能一次都不会执行
- 语法
while(条件){
循环体 条件成立需要重复执行的代码
}
- 示例
var num = 0;
while(num<5){
console.log('条件成立执行')
num++;
}
注意
if小括号的结果一定是布尔类型
if中小括号里面的代码
1.常用的是关系表达式
2.直接写布尔类型的值
3.写其他的值 编译器会帮我们转布尔类型Boolean(数据)再来判断是否成立
避免写一个死循环
- 穷举
猜谜游戏
生成以1-100之间的随机整数 让用户猜
如果用户猜大了或猜小了 提示用户 直到用户猜对为止
var num = Math.ceil(Math.random() * 100);
console.log(num);
//搞个死循环 直到猜对为止
while (true) {
var guess = +prompt('请输入数字');
if (guess == num) {
alert('猜对了');
//结束循环用break
break;
} else if (guess > num) {
alert('猜大了');
} else {
alert('猜小了');
}
}
do-while循环结构
- 适用于循环次数不固定 循环体无条件执行一次
- 特点 循环体无条件执行一次循环体
- 先斩后奏
- 先执行一次循环体 后判断条件
do{ 循环体 无条件执行一次循环体 再判断条件是否成立 }while(条件)
var num = 0;
do{
console.log('无条件执行一次再做判断');
num++;
}while(num<4)
-
测试题
登录案例 弹出一个登录框让用户输入码用户名和密码 只要输入正确提示正确 输入错误就重复输入 直到输入正确为止 账号admin 密码123456
do{
var usrname = prompt('请输入用户名');
var pwd = prompt('请输入密码');
}while(usrname !='admin'|| pwd != '123456);
for循环
- 适用于循环次数固定的场景
for(声明循环变量;循环条件;循环变量自增){循环条件成立执行代码}
- for循环执行步骤
1.执行 声明循环变量
2.执行 判断循环条件
3.条件成立 执行大括号代码 条件不成立 循环结束
4.执行 循环变量自增 重复步骤2
注意
小括号里面是以分号隔开
小括号里面的语句可以省略 但是分号不能省略
if(;;){}
- 箩筐思想
//声明一个空箩筐
var sum = 0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
- 打擂台思想
//声明一个擂主 -Infinity
var max = -Infinity;
for (var i = 1; i <= 5; i++) {
var num = +prompt('请输入第' + i + '个数');
if (num > max) {
max = num;
}
}
console.log(max);
循环中的关键字
- break
结束循环语句 立即执行大括号后面的代码 - continue
结束本次循环体 立即进入下一次循环判断
注意
break关键字可以用于三种循环结构以及switch-case分支结构
continue关键字只能用于三种循环结构
-
测试
穷举: 从1遍历到无穷大寻找符合条件的数字 有一群人 如果3个人站一排多出1个人 如果4个人站一排对出2个人 如果5个人站一排多出3个人 请问这群人有多少人
for (var i = 1; i < Infinity; i++) {
if (i % 3 == 1 && i % 4 == 2 && i % 5 == 3) {
console.log(i);
break;
}
}
循环嵌套
- 打印正方形
- 外层循环决定多少行 内层循环决定多少列
for (var j = 1; j <= 5; j++) {
//让里面的5个*循环5次 并回车
for (var i = 1; i <= 5; i++) {
//打印* 和一个空格 ;
//一行打印出5个*
document.write('* ');
}
document.write('<br>')
}
- 打印三角形
for (var j = 1; j <= 5; j++) {
for (var i = 1; i <= j; i++) {
document.write('* ');
}
document.write('<br>')
}
- 打印倒三角形
for (var j = 1; j <= 5; j++) {
for (var i = 1; i <= (6-j); i++) {
document.write('* ');
}
document.write('<br>')
}
- 打印九九乘法表
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
document.write(j+'*'+i+'='+j*i+' ');
}
document.write('<br>')
}
-
循环练习
老师问学生 这道题你会了吗(y/n)? 如果学生会就回去,不会, 老师再问一遍 这道题你会了吗(y/n)? 在六遍以内不会都可以回家.
//法1 用do-while
var count = 1;
do {
var isHui = prompt('第' + count + '次会了吗?y/n');
count++;
} while (isHui == 'n' && count <= 6);
alert('不管会不会都会回家吧')
//法2 用for循环
var count = 1;
for (var i = 1; i <= 5; i++) {
var isHui = prompt('第' + count + '次会了吗?y/n');
count++;
if (isHui == 'y') {
break;
//会了退出循环
}
}
i == 6 ? alert('五次都不会') : alert('会了')
录入5个人的年龄并计算平均年龄,重复输入五次.
如果有人搞鬼输入负数或大于100的数,立即停止输入并报错,
还算出之前输入的个数和平均值打印出来
var sum = 0;
for (var i = 1; i <= 5; i++) {
var age = +prompt('请输入第' + i + '个人的年龄');
if (age < 0 || age > 100) {
alert('出错');
break;
}
sum += age;
}
console.log('之前输入的个数' + (i - 1) + '平均值是' + sum / (i - 1));
2006年培养学员80000人.年数2006年开始,人数80000起步 每年呈25%的增长速度.问需要几年到20万人
//法1 用do-while
var num = 80000;
var year = 2006;
do {
num *= 1.25;
year++;
} while (num < 200000)
console.log(year);
//法2 用for循环
var num = 80000;
for (var i = 2006; i < Infinity; i++) {
if (num < 200000) {
num *= 1.25;
}else{
break;
}
}
alert(i);
用户输入正确,提示登录成功 输入错误,提示继续输入 输错3次,提示账号被冻结,不能再输入,跳出循环,结束
//法1 用do-while
var count = 1;
do {
var usr = prompt('请输入用户名');
var pwd = prompt('请输入密码');
count++;
} while ((usr != 'admin' || pwd != '123456') && count <= 3);
count == 4 ? alert('账号被冻结') : alert('登录成功');
//法2 用for循环
for (var i = 1; i <= 3; i++) {
var usr = prompt('请输入用户名');
var pwd = prompt('请输入密码');
if (usr == 'admin' && pwd == '123456') {
break;
}
}
i == 4 ? alert('账号被冻结') : alert('登录成功');
1000~ 5000之间有多少整数,其各位数字之和为5,分别是哪些数(例如整数2003的各位数字之和为 2+0+0+3 ,等于5)),并统计满足条件的整数有多少个。
var count = 0;
for (var i = 1000; i <= 5000; i++) {
var q = parseInt(i / 1000);
var b = parseInt(i % 1000 / 100);
var s = parseInt(i % 100 / 10);
var g = parseInt(i % 10);
if (q + b + s + g == 5) {
count++;
console.log(i);
}
}
console.log(count + '个');
数组
数组三要素
- 元素
数组中存储的数据 - 下标
元素的位置(从0开始)
最大下标 = 数组名.length - 1
数组名.length = 最大下标 + 1
- 长度
元素的数量
//数组的声明
var arr = [10,20,30];
//数组的取值: 数组名[下标]
console.log(arr[0];
//数组的长度: 数组名.length
console.log(arr.length);
注意
在数组取值中
如果没有超过最大下标 则取出对应下标的值
如果超过最大下标 获得的是undefined
在数组赋值中
如果没有超过最大下标 则修改原有的数据
如果超过最大下标 则动态添加数据
- 不连续数组
没有赋值的都是undefined
var arr = [10,20,30];
arr[4] = 50;
//下标为3没有赋值 则结果为undefined
console.log(arr[3]);//undefined
- 获取数组的最后一个元素
arr[arr.length-1]
- 在数组最后添加一个元素
arr[arr.length] = 值
- 删除数组最后一个元素
arr.length--
遍历数组
- 获取数组中每一个元素
var arr = [10,20,30];
for(var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
- 翻转数组
//法1 倒序遍历 存入新数组
var arr = [10, 30, 9, 20, -5, 6, 8];
//声明一个空数组 保存翻转的元素
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
};
console.log(newArr);
//法2 同法1
var arr = [10, 30, 9, 20, -5, 6, 8];
//声明一个空数组 保存翻转的元素
for(var i=arr.length-1;i>=0;i--){
newArr.push(arr[i])
};
console.log(newArr);
// 交换法 遍历一半 让下标为i的元素与下标为arr.length-1-i元素交互位置
/*
0 与 arr.length-1 交换位置
1 与 arr.length-1-1 交换位置
...
i 与 arr.length-1-i 交换位置
*/
for (var i = 0; i < arr.length / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
console.log(arr);
- 斐波那契数列
//1 1 2 3 5 8 13 21 44 ... 求第10列(下标9)
var arr = [1, 1];
for (var i = 2; i < 10; i++) {
arr[i] = arr[i - 2] + arr[i - 1];
}
console.log(arr[arr.length - 1]);
- 冒泡法排序
- 核心原理
数组中相邻两个元素比较大小 然后交换位置
//冒泡排序
var arr = [10, 2, 9, -6, 66, 99, 5];
/*
外层比较轮数
第一轮找第一大 第二轮找第二大 第三轮找第三大... 所以7个元素只需比较6轮
所以arr.length 需要比较 arr.length-1轮
*/
for (var i = 0; i < arr.length - 1; i++) {
/* 内层比较每一轮比较的次数 数组中两两比较
最后一次没意义 7个元素比6次即可
(i=0)第一轮比较arr.length-1次
(i=1)第二轮比较arr.length-2次
...
每一轮比较次数+i = arr.length-1
所以每一轮比较次数 需要比较arr.length-1-i
*/
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
二维数组(了解)
- 数组中每一个元素都是数组
var arr = [[10, 20, 30], [40, 50, 60], [70, 80, 90]];
for (var i = 0; i < arr.length; i++) {
// 取出数组中的数组
console.log(arr[i]);
for (var j = 0; j < arr[i].length; j++) {
// 取出二维数组中的值
console.log(arr[i][j]);
}
}
数组的声明方式
-
简洁语法
var arr = [10,20,30];
-
标准语法
var arr = new Array();
var arr = new Array(10);
var arr = new Array(10,20,30);
-
两种声明方式的区别
相同点: 当数组中有多个元素的时候 含义相同 只是语法不同
不同点: 当数组中只有一个元素的时候 含义不同
var arr = [10];
代表数组中只有一个元素 值为10
var arr = new Array(10);
代表数组长度为10的空数组
数组去重
- 冒泡法
//数组去重
//法1 冒泡法
var arr = [20, 25, 88, 66, 90, 25, 88, 66];
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
// 得到从小到大的冒泡排序
console.log(arr);
//在判断相邻两个元素之间是否相等 如果不等 就添加到新数组中
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != arr[i + 1]) {
// 追加到新数组中 两种方式都可以
// newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr);
- 开关思想
//数组去重
//法2 开关思想
var arr = [20, 25, 88, 66, 90, 25, 88, 66];
//声明一个新数组 存放去重后的元素
var newArr = [];
for (var i = 0; i < arr.length; i++) {
// 判断新数组中是否存在一样的元素 通过开关思想
//提出假设 假设不在
var buZai = true;
for (var j = 0; j < newArr.length; j++) {
// 推翻假设
if (arr[i] == newArr[j]) {
buZai = false;
//存在一样的元素 结束循环
break;
}
}
if (buZai) {
// 追加到新数组的两种方式都可以
// newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr);
- indexOf检测
//数组去重
//法3 indexOf检测
var arr = [20, 25, 88, 66, 90, 25, 88, 66];
//声明一个新数组 存放去重后的元素
var newArr = [];
//遍历arr
for (var i = 0; i < arr.length; i++) {
// indexOf(元素) 如果存在会返回下标 如果不存在会返回-1
if (newArr.indexOf(arr[i]) == -1) {
// 追加到新数组的两种方式都可以
// newArr[newArr.length] = arr[i];
newArr.push(arr[i])
}
}
console.log(newArr);
- 对象法
//数组去重
//法3 indexOf检测
var arr = [20, 25, 88, 66, 90, 25, 88, 66];
//声明一个新数组 存放去重后的元素
var newArr = [];
//声明一个空对象 用来检测元素是否重复
var obj = {};
//遍历arr
for (var i = 0; i < arr.length; i++) {
if (obj[arr[i]] == undefined) {
// 追加到新数组的两种方式都可以
// newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
obj[arr[i]] = 1;
}
}
console.log(newArr);
-
测试题
将字符串数组用`|`分割成字符串
//原生操作
var arr = ['中国', '我', '爱', '你'];
// 声明一个空字符串 存放数组中的值
var str = '';
for (var i = 0; i < arr.length; i++) {
str += arr[i];
// 最后一个字后面不需要|分割 所以判断只要不是最后一个 就添加|
if (i != arr.length - 1) {
str += '|'
}
}
console.log(str);
//通过数组的API操作
//arr.join("自定义分隔符");
//自动将数组转为字符串
var arr = ['中国', '我', '爱', '你'];
console.log(arr.join('|'));
将数组中为0的那些值去掉
var arr = [10, 20, 0, 0, 30, 0, 0, 50];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i]
}
}
console.log(newArr);
函数
- 将代码存入函数中 实现代码复用
语法
- 声明函数
function 函数名(形参){函数体}
- 调用函数: 执行函数体代码
函数名(实参)
- 函数传参的本质 是一个变量赋值的过程
实参给形参赋值
形参与实参不需要一一对应 如果没有传 默认值就是undefined
循环与函数有着本质的区别
从数据层面上
函数是一种数据类型 存储的是代码
循环是一种语法 让代码重复执行
从作用上
函数是一段代码在多个地方执行一次
循环是一段代码在一个地方执行多次
- 在函数外部无法访问函数内部声明的变量
- 要想拿到函数内部的结果 可以在函数中return这个结果 然后用一个变量接收这个返回值后打印
函数的三要素
- 函数体(功能)
- 参数
- 返回值
函数中的关键字return
- 只能写在函数体中
- 作用
结束函数调用 后面的所有代码都不执行 - 返回值 : 函数传递数据给调用者
return 值
函数的执行方式
- 调用者传递数据给函数
- 函数通过返回值将结果传递给调用者
- 调用者用变量接收返回值或直接调用打印
函数的工作流程
- 声明函数
- 调用者传参
- 执行函数体代码
- 函数将结果返回给调用者
- 求任意n到m之间的和
function getSum(n, m) {
var sum = 0;
for (var i = n; i <= m; i++) {
sum += i;
}
return sum;
}
//假设求1到100之间的和
//调用后用变量接收返回值
var res = getSum(1, 100);
console.log(res);
//直接调用打印
//console.log(getSum(1, 100));
- 求任意半径圆的面积
function getArea(r) {
var area = Math.PI * Math.pow(r, 2);
return area;
}
//假设需要求半径为10 直接调用传入值
var res = getArea(10);
console.log(res);
返回值的注意点
- 如果一个函数没有return 返回值是undefined
- 如果一个函数有return 但是后面没有值 返回值是undefined
- 只有函数写了return且return后面有值 返回值就是return后面的值
- return后 后面的代码不会执行
- 求数组的最大值 用函数封装
//求数组的最大值
function getMax(arr) {
var max = arr[0];
for (var i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i]
}
}
return max;
}
var newArr = [10, 20, 6, 30, 99];
var res = getMax(newArr);
console.log(res);
变量的作用域
- 变量作用域: 变量起作用的范围
- 全局作用域: 全局变量 函数外面声明的变量 在页面任何位置起作用
//全局变量
var num = 10;
console.log(num);//10
- 局部作用域: 局部变量 函数里面声明的变量 在函数内部起作用
function fn(){
//局部变量
var num = 10;
console.log(num);//10
}
//局部变量在函数外部访问会报错
console.log(num);//报错
作用域链
默认情况下 js代码处于全局作用域(0级链)
声明一个函数 就会开辟一个新的局部作用域(1级链)
在函数内部又可以声明函数 形成局部作用域(2级链)
在函数内部又可以声明函数 形成局部作用域(3级链)
以此类推 就形成作用域链
- 变量在作用域链的访问规则
- 就近原则
- 当在一个作用域访问变量时 会先从当前作用域寻找变量的声明
- 如果有就访问 如果没有则从父级链中寻找声明
- 有则访问 没有则继续从父级链中寻找 以此类推
- 直到顶级链 如果顶级链还找不到 程序则报错
var num = 10;//0级链
function fn1(){//0级链
var num = 20;//1级链
console.log(num);
function fn2(){//1级链
var num = 30;//2级链
console.log(num);//30
}
fn2();
}
fn1();
console.log(num);//10
- js中只有函数可以开辟局部作用域
//分支结构中声明的变量是全局变量
if (1 > 0) {
//全局变量
var num = 10;
}
console.log(num);//10
console.log('------------------');
//循环结构中声明的变量也是全局变量
for (var i = 0; i <= 5; i++) {
}
console.log(i);//6
console.log('------------------');
var name = '张三'
function fn() {
//没有var关键字声明的变量是全局变量
//将全局变量中的值重新赋值
name = '李四';
console.log(name);//李四
}
fn();
console.log(name);//李四
js预解析
- js代码在执行代码之前 有一个预解析过程
- 预解析: js代码从上往下执行之前 编译器会将代码进行变量提升
- 变量提升:
- var关键字声明会提升到当前作用域最顶端 赋值语句在原地
- function关键字函数声明也会提前 调用语句在原地
- 预解析的意义(作用): 可以让函数在任何地方调用
- 如果一个变量没有用var关键字声明 不管写在任何位置 都是全局变量 不参与预解析
- js预解析面试题
- 题1
var num = 10;
fun();
function fun() {
console.log(num);//undefined
var num = 20;
}
console.log(num);//10
//预解析过程
// var num ;
// function fun(){
// var num;
// console.log(num);//undefined
// num = 20;
// }
// num = 10;
// fun();
// console.log(num);//10
- 题2
console.log(a);//打印a整個函數
a();//我是函数
var a = '我是变量';
function a() {
console.log('我是函数');
}
a();//报错
console.log(a);
//预解析过程
// var a;
//变量重新声明
// function a() {
// console.log('我是函数');
// }
// console.log(a);
// a();//调用后打印函数里的代码-->我是函数
// a = '我是变量';
// a();//此时a中存储的是字符串 没有调用的语法 报错 程序报错 后面的代码不会执行
// console.log(a);
- 题3
console.log(a);
var a = '我是变量';
function a() {
console.log('我是函数');
}
console.log(a);//'我是变量'
//预解析过程
//function和var都是声明作用 变量名相同 就是重新声明
// var a;
// function a(){
// console.log('我是函数');
// }
// console.log(a);//打印出整个a函数
// // 没有var关键字声明 就是变量重新赋值
// a = '我是变量';
// console.log(a);//'我是变量'
函数声明
- 函数声明(具名函数)
function fn(){}
- 表达式声明(匿名函数)
var fn = function(){}
两种声明方式唯一的区别
函数声明可以在任何地方调用
表达式声明只能在声明之后调用
值类型与引用类型
- 变量的声明是在栈中开辟空间
- 值类型(string number boolean undefined null)
基本数据类型栈中存储的是数据 赋值拷贝的也是数据 修改后的数据对原数据没有影响 - 引用类型(Array Object)
复杂数据类型栈中存储的是地址 数据存储在堆中 赋值拷贝的是地址 修改拷贝后的数据对原数据有影响
var a = 10;
var b = a;
b = 20;
console.log(a);
console.log(b);
var arr1 = [10,20,30];
var arr2 = arr1;
arr2[0] = 100;
console.log(arr[1]);
console.log(arr[2]);
函数中关键字arguments
- 函数实参与形参可以不一一对应 但是赋值是按顺序赋值的
- 函数中arguments关键字 存储所有的实参 只能在函数中使用
- 函数中arguments关键字 是一个伪数组 拥有数组的三要素(元素 下标 长度) 没有数组的API
- 函数中arguments关键字与形参一一对应
- 修改了arguments 形参也会改
- 修改了形参 arguments也会修改
function fn(a) {
//存储所有的实参
console.log(arguments);
//arguments与形参一一对应
// arguments修改了 形参也跟着修改
arguments[0] = 10;
console.log(a);
// 形参修改了 arguments也跟着修改
a = 20;
console.log(arguments);
}
//函数中实参与形参不需要一一对应
fn(1, 2, 3);
- 函数中arguments关键字的应用场景
让函数根据参数的数量实现不同的功能
//需求
//一个参数 打印参数
//两个参数 求和
//三个参数 其他功能
function fn() {
if (arguments.length == 1) {
console.log(arguments[0]);
} else if (arguments.length == 2) {
console.log(arguments[0] + arguments[1]);
} else {
console.log('其他功能');
}
}
fn(10);
fn(10, 20);
fn(10, 20, 30);
-
函数练习
写一个函数,实现翻转数组
//写一个函数,实现翻转数组
//方法1 通过倒序遍历 存入新数组中
function fn(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var myArr = [10, 20, 30, 40, 50];
var res = fn(myArr);
console.log(res);
//方法2 通过交换法 遍历一半
function fn(arr) {
for (var i = 0; i < arr.length / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - 1 - i] = temp;
}
return arr;
}
var myArr = [10, 20, 30, 40, 50];
var res = fn(myArr);
console.log(res);
写一个函数,既可以实现对数组排序从小到大,也可以从大到小
function getSort(arr, flag) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (flag ? arr[j] > arr[j + 1] : arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var myArr = [10, 2, 30, 6, 9, -5, 0];
//true 从小到大排序
// var res1 = getSort(myArr,true);
//false 从大到小排序
var res2 = getSort(myArr, false);
// console.log(res1);
console.log(res2);
写一个判断平年闰年的函数
//输入一个年份,判断是否是闰年[闰年:能被4整数并且不能被100整数,或者能被400整数]
//方法1
function getYear(year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
// true闰年
return true;
} else {
//false平年
return false;
}
}
var myYear = +prompt('请输入一个年份');
var res = getYear(myYear);
console.log(res);
//方法2
function getYear(year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
var myYear = +prompt('请输入一个年份');
var res = getYear(myYear);
console.log(res);
写一个函数输入某年某月某日,判断这一天是这一年的第几天
function getDay(year, month, day) {
var arr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
arr[1] = 29;
};
//存储总天数
var days = 0;
for (var i = 0; i < month - 1; i++) {
days += arr[i]
}
days += day;
return days;
}
var usrYear = +prompt('请输入年')
var usrMonth = +prompt('请输入月')
var usrDay = +prompt('请输入日')
var res = getDay(usrYear, usrMonth, usrDay);
console.log(res);
写一个函数,可以随机生成十六进制颜色 ( #abcdef );
function getColor() {
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
var str = '#';
for (var i = 0; i <= 6; i++) {
var index = Math.floor(Math.random() * 16);
str += arr[index];
}
return str;
}
console.log(getColor());
回调函数
如果一个函数的参数是一个函数 这个函数称之为回调函数
function a() {
console.log('a中的函数');
}
function fn(c) {
console.log('fn中的函数');
c();
}
fn(a)
//fn()调用后 会先执行函数里面的代码 实参a传入形参c中 实参a是个函数 函数中调用了c()也就是调用了a() 会执行a函数中的代码
自调用函数
一个函数自己调用自己
- 常用于 匿名函数自调用
- 语法
(匿名函数(){})()
; - 作用 开辟了局部作用域 防止全局变量污染
对象
- 一个对象存储多个数据
- 多个属性之间用逗号隔开
对象的声明
- 简洁方式
对象的初始化语法(声明的时候赋值)
var 对象名 = {'属性名':'属性值','属性名':'属性值'}
- 标准方式 (构造函数方式)
var 对象名 = new Object({'属性名':'属性值','属性名':'属性值'});
对象的取值
- 语法
- 点语法:
对象名.属性名
- 字符串语法 :
对象名['属性名']
- 点语法:
- 如果有这个属性 则获取这个属性值
- 如果没有这个属性 会动态添加这个属性名 但是这个属性没有属性值 所以获取属性值结果是undefined
对象的赋值
- 如果有这个属性 则是修改对应的属性值
- 如果没有这个属性 则是动态添加属性
var p = {
name: 'jack',
age: 18
}
var name = 'age';
console.log(p.name);//jack
console.log(p.age);//18
console.log(p['name']);//jack
console.log(p['age']);//18
//字符串语法 取name变量中存储的字符串对应的属性值
console.log(p[name]);//18
var a = 'name';
//点语法取a属性名的值 a不存在 结果是undefined
console.log(p.a);//undefined
console.log(p[a]);//jack
对象与数组的异同点
相同点 : 一个变量存储多个数据
不同点 :
数组 有序存储 下标与数据一一对应 下标从0开始递增
对象 无序存储 属性名与数据一一对应 (键值对)
遍历对象
- 获取对象中所有的属性值
- for-in循环
for(var key in obj){}
- key变量中存储的是对象的属性名字符串
- 不能用点语法obj.key 获取的是key这个属性的值
- 只能用字符串语法obj[key] (key中存储的是字符串数据)
方法中的this关键字
谁调用这个方法 this指向谁
var p = {
name: 'jack',
age: 18,
sayHi: function () {
console.log('我是' + this.name);
}
}
//p调用 this指向p
p.sayHi();
使用普通函数声明多个对象
//使用函数声明多个对象
function createPerson(name, age) {
//声明一个空对象
var person = {};
//赋值 对象中不存在的属性会动态添加
person.name = name;
person.age = age;
//返回对象
return person;
}
var p1 = createPerson('张三', 18);
console.log(p1);//{name: "张三", age: 18}
var p2 = createPerson('李四', 18);
console.log(p2);//{name: "李四", age: 18}
使用自定义构造函数声明多个对象
- 调用函数时 前面加了new关键字
- 优点 代码简洁
- new关键字的作用
- 创建空对象
- 将this指向这个对象 this={}
- 完成对象的赋值(执行构造函数中的代码)
- 自动帮我们返回这个对象 return this
function CreatePerson(name, age) {
//赋值 对象中不存在的属性会动态添加
this.name = name;
this.age = age;
}
var p1 = new CreatePerson('张三', 18);
console.log(p1);//{name: "张三", age: 18}
var p2 = new CreatePerson('李四', 18);
console.log(p2);//{name: "李四", age: 18}
注意
自定义构造函数必须要用new关键字来调用
自定义构造函数的函数名一般首字母大写
如果在自定义构造函数中手动添加了return关键字
在基本数据类型中无效 在复杂数据类型中会覆盖new创建的那个对象
js对象
- 自定义对象
程序员自己声明的对象 - 内置对象
js作者提前写好的对象 里面存储了一些写好的属性和方法 方便开发者使用
- json对象
解决跨平台兼容性问题
所有编程语言都支持的一种对象类型 主要解决不同平台之间的数据传输
json对象
json对象与js对象的区别
json对象的属性名和属性值都要是字符串 用双引号括起来
使用上没有区别 只是数据处理方式不一样
内置对象
API(application programming interface): 对象的方法
Date对象
- 创建时间对象
var date = new Date()
- 转换格式
//根据本地时间格式,把 Date 对象转换为字符串。
console.log(date.toLocaleString());
console.log(date.toLocaleDateString());
console.log(date.toLocaleTimeString());
- 获取年月日时分秒
console.log(date.getFullYear());//年
console.log(date.getMonth());//月 月份范围0-11
console.log(date.getDate());//日
console.log(date.getDay());//星期 星期范围0-6 星期天到星期六
console.log(date.getHours());//时
console.log(date.getMinutes());//分
console.log(date.getSeconds());//秒
console.log(date.getMilliseconds());//毫秒
Date日期对象方法 | 描述 |
---|---|
Date() | 返回当前的日期和时间 |
toLocaleString() | 根据本地时间格式,把 Date 对象转换为字符串返回当前的日期和时间。 |
toLocaleDateString() | 根据本地时间格式,把 Date 对象转换为字符串。返回当前的日期 |
toLocaleTimeString() | 根据本地时间格式,把 Date 对象转换为字符串。返回当前的时间 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
注意
日期对象获取的月份是从0-11
当前为7月 获取的是下标6
日期对象获取的星期是从0-6
星期天到星期六 星期天获取的是下标0
- 创建自定义日期
参数可以使自定义的 也可以是固定格式的时间字符串
//自定义的参数 月份要对应日期对象的下标
//如果当前是11月 那么要写下标10
var date1 = new Date(2017, 10, 3, 09, 30, 20);
console.log(date1);
//固定格式的时间字符串 'YYYY-MM-DD HH:mm:ss'
var date2 = new Date('2017-11-03 09:30:20')
console.log(date2);
Array对象
concat()
拼接两个数据
返回值: 拼接后的数组
var arr = [63, 9, 9, 10];
var arr1 = [10, 20];
//concat() 拼接数组
console.log(arr.concat(arr1));//[63, 9, 9, 10, 10, 20]
join()
将数组元素拼接成字符串
参数: 指定分隔符 默认是以逗号隔开
返回值: 拼接之后的字符串
var arr2 = ['我', '爱', '你', '中国']
//join()以指定分隔符将数组拼接成字符串 默认以逗号隔开
console.log(arr2.join());//'我,爱,你,中国'
console.log(arr2.join('|'));//'我|爱|你|中国'
pop()
删除数组的最后一个元素
同arr.length--
返回值: 删除的那个元素
//pop() 删除数组的最后一个元素
//返回值是删除的那个元素
var arr = [63, 9, 2, 10];
arr.pop();
console.log(arr);// [63, 9, 2]
var last = arr.pop();
console.log(last);//2
push()
往数组后面添加元素
同arr[arr,length]=值
返回值: 新数组的长度
//push() 往数组后面添加元素
//返回值是新数组的长度
var arr = [63, 9, 2, 10];
arr.push(1, 2, 3);
console.log(arr);//[63, 9, 2, 10, 1, 2, 3]
var length = arr.push();
console.log(length);//7
reverse
翻转数组
//reverse() 翻转数组
var arr = [63, 9, 2, 10];
arr.reverse();
console.log(arr);//[10, 2, 9, 63]
shift()
删除数组的第一个元素
返回值是删除的那个元素
//shift() 删除数组的第一个元素
//返回值是删除的那个元素
var arr = [63, 9, 2, 10];
arr.shift();
console.log(arr);//[9, 2, 10]
var first = arr.shift();
console.log(first);//9
console.log(arr);//[2, 10]
slice(start,end)
查找数组元素
[开始下标,结束下标)
//slice(开始下标,结束下标) 查找数组元素 [开始下标,结束下标)
var arr = [63, 9, 2, 10];
console.log(arr.slice(0, 2));//[63, 9]
sort()
排序 参数是一个函数
从小到大排序 function(a,b){return a-b}
从大到小排序 function(a,b){return b-a}
/*sort() 排序
参数是一个函数
从小到大排序 function(a,b){return a-b}
从大到小排序 function(a,b){return b-a}
*/
var arr = [63, 9, 2, 10];
console.log(arr.sort(function (a, b) {
return a - b;
}));//[2, 9, 10, 63]
console.log(arr.sort(function (a, b) {
return b - a;
}));//[63, 10, 9, 2]
splice()
删除元素 并向数组添加新元素
参数有三个
第一个参数是删除的元素下标
第二个参数是删除多少个元素
第三个参数可选 要添加的新元素
返回值是删除的元素
//splice(从哪里删,删几个,替换的元素)
//返回值是删除的那个元素
var arr = [63, 9, 2, 10];
arr.splice(1, 1);
console.log(arr);// [63, 2, 10]
console.log(arr.splice(1, 1));//[2]
arr.splice(0, 1, '替换的');
console.log(arr);// ["替换的", 10]
数组对象的方法 | 描述 |
---|---|
concat() | 连接两个或更多的数组,并返回结果。 |
join() | 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔 |
pop() | 删除并返回数组的最后一个元素 |
push() | 向数组的末尾添加一个或更多元素,并返回新的长度。 |
shift() | 删除并返回数组的第一个元素 |
unshift() | 向数组的开头添加一个或更多元素,并返回新的长度。 |
reverse() | 颠倒数组中元素的顺序。 |
sort() | 对数组的元素进行排序 参数是一个函数 |
slice() | 从某个已有的数组返回选定的元素 [开始下标,结束下标) |
splice() | 删除元素,并向数组添加新元素。第一个参数是删除的元素下标 第二个参数是删除多少个元素 第三个参数可选 要添加的新元素 返回值是删除的元素 |
String对象
length
属性
字符串的长度
//length属性 字符串的长度
var str = '我是Denisedan';
console.log(str.length);//11
charAt()
根据下标获取对应的字符
//charAt() 根据下标获取对应的字符
var str = '我是Denisedan';
console.log(str.charAt(0));//'我'
//也可以通过下标获取
console.log(str[0]);//'我'
concat()
拼接多个字符串
//concat() 拼接多个字符串
var str = '我是Denisedan';
var str2 = '大家好';
var res = str2.concat(str);
console.log(res);//大家好我是Denisedan
//也可以+号拼接
var res2 = str2 + '我是Denisedan';
console.log(res2);//大家好我是Denisedan
indexOf()
indexOf(‘字符’) 判断字符串是否包含某个字符
存在 返回首字符下标
不存在 返回固定值-1
/*indexOf('字符') 判断字符串是否包含某个字符
存在 返回首字符下标
不存在 返回固定值-1
*/
var str = '我是Denisedan';
console.log(str.indexOf('d'));//8
console.log(str.indexOf('6'));//-1
substr()
截取字符串
第一个参数是从哪个下标开始截取
第二个参数是截取几个字符
/*substr() 截取字符串
第一个参数是从哪个下标开始截取
第二个参数是截取几个字符
*/
var str = '我是Denisedan';
console.log(str.substr(0,8));
replace()
替换字符串
第一个参数是要替换的字符串
第二个参数是替换后的字符串
/*replace() 替换字符串
第一个参数是要替换的字符串
第二个参数是替换后的字符串
*/
var str2 = '大家好';
console.log(str2.replace('大家','你们'));//你们好
//将第二个参数设置成空字符串 就是删除字符串
var str2 = '大家好';
console.log(str2.replace('大家',''));//好
toLocaleUpperCase()
toLocaleLowerCase()
大小写转换
//大小写转换
var str = '我是Denisedan';
console.log(str.toLocaleUpperCase());//我是DENISEDAN
console.log(str.toLocaleLowerCase());//我是denisedan
split()
分割字符串
将字符串中字符以固定的分隔符分割成多个字符串 并且放入数组中
参数是指定分隔符 默认没有指定 则返回数组
/*split()分割字符串
将字符串中字符以固定的分隔符分割成多个字符串
并且放入数组中
参数是指定分隔符 默认没有指定 则返回数组
返回值一定是数组
*/
var str = '我&是&Denise&dan';
console.log(str.split());//["我&是&Denise&dan"]
console.log(str.split('&'));// ["我", "是", "Denise", "dan"]
字符串对象的方法 | 描述 |
---|---|
charAt() | 返回在指定位置的字符。根据下标获取对应的字符 |
concat() | 连接字符串 拼接多个字符串 |
indexOf() | 检索字符串 判断字符串是否包含某个字符 |
lastIndexOf() | 从后向前搜索字符串。 |
substr() | 从起始索引号提取字符串中指定数目的字符。截取字符串 第一个参数是从哪个下标开始截取 第二个参数是截取几个字符 |
substring() | 提取字符串中两个指定的索引号之间的字符。不包括最后一个索引号 |
replace() | 替换与正则表达式匹配的子串。修改字符串 第一个参数是要修改的字符串 第二个参数是修改后的字符串 |
split() | 把字符串分割为字符串数组。 |
toLocaleLowerCase() | 把字符串转换为小写。 |
toLocaleUpperCase() | 把字符串转换为大写。 |
字符串的恒定性
- 字符串无法被修改
- 字符串创建后 会缓存在字符串常量区 每次创建字符串 会先去字符串常量区查找是否有相同的字符串 有则直接使用 没有则创建
var str = '大家好';
str[0] = '小';
console.log(str);//大家好
- 所有api都不会改变原先的字符串 而是生成一个新的字符串
var res = str.replace('大', '小');
//字符串的api只是将字符串生成了一个新的字符串 原先的字符串没有发生改变
console.log(res);//小家好
// 字符串具有恒定性不会被修改
console.log(str);//大家好
基本包装类型
-
基本包装类型
基本数据类型包装成引用类型 -
js为了让基本数据类型可以像对象一样调用方法 会将基本数据类型转成特殊的对象类型
new String() new Number() new Boolean()
思考 此时num是一个基本数据类型 怎么可以通过点语法调用.toString() 呢?
var num = 10;
num.toString();答: 编译器会将num转成new Number(10) 再去进行调用.toString()
字符串与字符串对象的区别
都是字符串 字符串具有恒定性
字符串是基本类型
字符串对象是基本包装
js中的转义符
转义符 | 含义 |
---|---|
\' | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
\& | & |
\r | 回车符 |
\t | 制表符 |
\n | 换行符 |
\f | 换页符 |
\b | 退格符 |
逗号表达式与逗号运算符(了解)
- 逗号运算符
,
- 逗号表达式
(表达式1,表达式2,表达式3....)
- 运算规则
- 逗号运算符的每一个式子都会执行
- 逗号运算式的结果是最终一个式子的结果
var n1 = 10;
var n2 = 20;
var res = (n1++ , n1 + n2)
console.log(n1);//11
console.log(n2);//20
console.log(res);//31