二、JS运算符
算术运算符 + - * / %(取余数)
算数计算时,浮点数的精确度会有偏差,也不能直接比较两个浮点数 是否相等。
递增(减)运算符
前置:先自加1,在返回值;
后置(常用):先返回原值,在自加1。
比较运算符
等于符号 == 会默认转换数据类型,将字符串型数据转换为数字型,只要求数值相等;
全等于符号 === 要求数据类型和数值都要一样。
逻辑运算符——逻辑中断(短路运算)
逻辑与:表达式1 && 表达式2
若表达式1的值为真,则返回表达式2的值;若表达式1的值为假,则返回表达式1的值(运算中断)。
逻辑或:表达式1 || 表达式2
若表达式1的值为真,则返回表达式1的值(运算中断);若表达式1的值为假,则返回表达式2的值。
逻辑非 : !表达式
15-JS流程控制
顺序、分支(if、switch)、循环结构
三、循环
25-命名规则
变量名称一般用名词; 函数名称一般用动词。
四、数组(Array)
创建方法:
利用new关键字:
var 数组名 = new Array(2); //创建一个长度为2的空数组
var 数组名 = new Array(1,2); //数组[1,2]
利用数组字面量(就是中括号[ ]): var 数组名 = [1,2..];
访问数组元素: 数组名[索引]; (索引号从0开始)
数组长度: 数组名.length;
新增数组元素
通过修改length属性给数组扩容;
通过给新索引号的元素赋值,来新追加组元素。
算法:
翻转数组(巧用length)、冒泡排序
18-函数
声明函数: function 函数名() {...}
调用函数: 函数名();
当函数的形参和实参的个数不匹配时,
若实参多于形参——只取到形参的个数;
若实参少于形参——多余的形参定义为undefined,计算结果为NaN。
五、函数 / 作用域 / 预解析 / 对象
arguments 是函数的一个内置对象,存储了传递来的所有实参;
展示形式是伪数组(具有length属性、以索引方式存储区,但不具有数组的pop、push等方法)。
声明函数的两种方式:
利用函数关键字 —— function 函数名() {...}
利用函数表达式—— var 函数名 = function() {...}
JS作用域:变量在某个范围内有效,为了提高程序的可靠性和减少变量命名冲突。
全局作用域 —— 整个script标签或者js文件;
局部作用域 —— 函数内部;
全局变量 —— 在全局作用域声明的变量,以及在函数内部,没有声明直接赋值的变量;
(如 var a = b = c = 1; 等同于 var a = 1; b = 1; c = 1;
其中 a 被声明且赋值,b 和 c 只赋值没有声明。)
全局变量在浏览器关闭时才被销毁,局部变量在(函数)程序执行完毕后就会被销毁,更加节约内存资源。
作用域链:函数嵌套时,内部函数可以访问外部函数的变量,并且变量名相同时采取链式查找的方式来决定取哪个值(就近原则)。
JS预解析:js引擎运行时分为 预解析 和 执行代码 两步;
预解析是把代码中所有声明,即 var(变量提升)和 function(函数提升)提升到当前作用域的最前面,但不提升赋值操作。
对象:在JS中,一组无序的相关属性和方法的集合,如字符串、数组、函数等;
对象是由属性和方法组成的。
- 属性:事物的特征;
- 方法:事物的行为(函数形式)。
创建方法:
利用对象字面量(花括号{ })—— var 对象名 = { 属性名: 值, 方法名: function {..} ... }
利用new object —— var 对象名 = new Object (); 对象名. 属性名 = 值; ...
利用构造函数 —— 将对象里面的一些相同的属性和方法抽象出来封装到函数里面
function 构造函数名(形参1,形参2...) { //构造函数名的首字母要大写
this.属性 = 形参1;
this.方法 = function(形参2) {...};
}
//调用
var 对象名 = new 构造函数名(实参值1...);
对象名.方法(实参值2);
调用方法:
调用对象的属性:对象名. 属性名 或者 对象名 [ '属性名' ]
调用对象的方法:对象名. 方法名()
变量与属性都是用来存储数据的,函数与方法都是用来实现功能的;
但变量、函数是单独声明、赋值或调用的,而属性、方法依附于对象,且不需要声明。
遍历对象:
for (var k in 对象名) {
console.log(k); //输出属性名
console.log(对象名[k]); //输出属性值
}
六、内置对象 / 简单复杂数据类型传参
JS中的对象分为三种:自定义对象(上面讲的)、内置对象、浏览器对象;
内置对象是JS语言自带的一些对象,提供了一下常用的基本功能。
(1)Math对象
不是构造函数,所以不需要用new调用,直接使用里面的属性和方法即可。
Math.PI Math.max/min( )
Math.abs( ) 绝对值
Math.floor( ) 向下取整
Math.ceil( ) 向上取整
Math.round( ) 四舍五入( 特殊:.5往大的方向取)
Math.random() 随机返回一个 [0,1) 区间内的浮点小数 ;
扩展:得到一个两数之间的随机整数,包括两个数在内
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
(2)date对象
是一个构造函数,要用new创建日期对象:
var date = new Date(...);
括号里无参数时,返回当前时间;
也可以写入日期参数,字符串形式 '2020-5-1' 或 '2020/5/1'、数字形式 2020, 5, 1
格式化方法:
方法名 | 说明 |
date.getFullYear() | 获取当前日期的年份 |
date.getMonth() | 获取当前日期的月份,0~11,取值时要+1 |
date.getDate() | 获取当前日期是几号 |
date.getDay() | 获取当前日期是星期几,1~6,星期天是0,可用数组索引显示汉字 |
date.getHours() | 获取当前时间的小时数 |
date.getMinutes() | 获取当前时间的分钟数 |
date.getSeconds() | 获取当前时间的秒数 |
实现倒计时:
+new Date() 可以返回当前时间距离标准时间(1970.1.1)的总毫秒数;
思路:用时间戳的方法,先得到当前时间和目标时间的总毫秒数,然后两个毫秒数相减,再经过单位转换就可以得到倒计时剩余时间(天、时、分、秒)。
(3)数组对象
创建方法(见四)
检测是否为数组 —— 返回true/false:
- instanceof 运算符: 变量名 instanceof Array;
- Array.isArray(参数) (H5新增,ie9以上版本支持)
添加、删除元素:
方法名 | 说明 | 返回值 |
push(元素) | 在数组尾部添加一个或多个元素 | 数组长度 |
pop() | 删除数组最后一个元素,数组长度-1 | 被删除的元素值 |
unshift(元素) | 在数组头部添加一个或多个元素 | 数组长度 |
shift() | 删除数组第一个元素,数组长度-1 | 被删除的元素值 |
数组排序:
arr.reverse() ——翻转数组;
arr.sort() ——升序排列,有固定用法(若直接用arr.sort,会按元素第一个字符的大小排序)
arr.sort (function() {
return a - b; //升序排列
// return b - a; 降序排列
});
获取元素的索引号:
arr.indexOf(元素) ——从数组头部开始查找,只返回第一个参数元素的索引;
arr.lastIndexOf(元素) ——从数组尾部开始查找,找不到元素时返回-1。
将数组转换为字符串:
arr.toString() ——将数组中所有元素转换为一个字符串,以逗号分隔
arr.join('分隔符'(默认逗号))
......
(4)字符串对象
基本包装类型:将简单数据类型包装成为复杂数据类型;
——String、Number、Boolean
字符串所有的方法都不会修改字符串本身,会返回一个新的字符串。
在底层,字符串是以字符数组的形式存储的。
获取字符串中某一字符的索引号:
str.indexOf ( '要查找的字符', [查找起始位置] );
lastIndexOf 类似
获取字符串中某一位置的字符:
str.charAt (index) —— 可以用来遍历字符串,依次返回每一个字符;
str.charCodeAt (index) —— 获取字符ASCII值,可以用来判断按了哪个键;
str[index] ——H5新增
拼接字符串: str.contact (参数1,参数2...)
截取字符串: str.substr (截取的起始位置, 截取的字符个数)
替换字符: str.replace ('被替换的字符', '替换为的字符') ——只替换第一个字符
字符串转换为数组: str.split ('分隔符') —— 字符串中的分隔符,若没有则写空''
(join 将数组转换为字符串 )
简单数据类型:
又成为值类型,有五种(见(一));
其中特殊的:null 的返回类型是复杂类型object,所以如果想把一个变量存为对象类型,但又暂时为空,就可以赋值为null。
复杂数据类型:
又称为引用类型,通过new关键字创建,如Object、Array、Date等。
两种数据类型的内存分配和传参过程:
简单 —— 在变量中存储的是值本身,存放在栈空间中;
简单数据作为实参传递给函数的形参,是将值复制给了形参,所以函数内对形参的操作不会影响到外部的变量,即外部的简单数据的值不会改变。
复杂 —— 实际值存放在堆空间中,但在变量中存储的是(引用)地址(十六进制表示),是存放在栈空间中,通过地址指向堆空间中的值;
复杂数据作为实参传递给函数的形参,是将变量存放在栈空间的地址复制给了形参,所以所以函数的操作会影响地址指向的实际值,即外部复杂数据的值也会改变。
9.23