目录
案例二“olangodfueoaosood”查找字符串中所有o出现的位置
数据在内存中存储
简单数据类型:Number、String、Boolean、Null、Undefined。简单类型存储在内存中的栈上
复杂数据类型: Object、数组。复杂数据类型存储在内存中的堆上
注意:JavaScript中没有堆栈的概念,只是我们通过堆栈的方式来解释以便让大家更容易理解代码的一些执行方式,便于将来学习其他语言。
需要了解的有:
- 简单类型作为函数的参数,在内存中如何存储。 形参的改变不会影响实参的改变。
- 复杂类型作为函数的参数,在内存中如何存储。 注意:此时形参的改变会影响实参的改变
注意:只有new一个对象才会在堆中开启一个内存空间。
内置对象
- JavaScript组成: ECMAScript 、 BOM、 DOM
- ECMScript的主要内容: 变量、注释、数据类型、类型转换、操作符、流程控制语句(判断和循环)、数组、对象、构造函数、内置对象
- JavaScript中的内置对象有三种:自定义对象、内置对象、浏览器对象
- ECMAScript中的对象:自定义对象、内置对象
- 内置对象:Math/Array/Date....
- 我们只需要了解内置对象最常用的属性和方法即可,其他需要使用或了解的可以查文档,
学习一个内置对象的使用,只要学会其常用的成员的使用(通过查文档学习)
通过查W3C文档还可以查MDN文档(一个最具权威的前端文档,网址为:developer.mozilla.org)
内置对象方法有很多,我们只需要知道内置对象提供的常用方法,使用时查询文档即可。
MDN
Mozilla开发者网络(MDN)提供有关开放网络技术(Open Web)的信息,包括HTML、CSS和万维网及HTML5应用的API。
如何学习一个方法?需要关注什么?
- 方法的功能
- 参数的意义和类型
- 返回值意义和类型
- demo进行测试
内置对象的Math对象
Math对象不是构造函数,它具有数学常数和函数的属性和方法,都是以静态成员方式提供,跟数学相关的运算来找Math中的成员(求绝对值、取整)
常用的Math成员
静态成员 含义 Math.PI 圆周率 Math.random( ) 生成随机数 Man.floor( )/Math.ceil( ) 向下取整/向上取整 Math.round( ) 取整,四舍五入 Math.abs( ) 绝对值 Math.max( )/Math.min( ) 求最大和最小值 Math.sin( )/Math.cos( ) 正弦/余弦 Math.power( )/Math.sqrt( ) 求指数次幂/求平方根 案例一随机生成颜色RGB
rgb格式 rgb(0,255,130).0-255范围
function random(min,max) { return Math.follr(Math.random() * (max - min + 1) + min); } function randomRGB(min, max) { var color1 = random(min, max); var color2 = random(min, max); var color3 = random(min, max); return 'rgb(' + color1 + ',' + color2 + ',' + color3 + ')'; } console.log(randomRGB(0, 255));
案例二模拟实现Math里面的max()/min()
我们知道,内置对象中使用静态成员的形式为 Math.max( ) 、 Math.min( ),那么这里的max()、min()是一个方法,而且这两个方法是属于Math对象的,因此我们不能只是像前面那样把max()写成一个function函数,而是要把它写进一个对象里。
注意:在比较谁大谁小时,我们不清楚参数到底有多少个,所有这时候我们定义max方法时一定不要写参数,而是用到arguments
var MyMath = { max: function () { var max =arguments[0]; for (var i = 1; i < arguments.length; i++){ if(max < arguments[i]) { max = arguments[i]; } } return max; } min: function () { var min =arguments[0]; for (var i = 1; i < arguments.length; i++){ if(min > arguments[i]) { min = arguments[i]; } } return min; } }
内置对象的Date对象
是一个构造函数,首先要通过new Date( )来创建日期实例(或对象)来实例成员。而不像Math对象,Math不是构造函数,里面提供的是静态成员。
var d = new Date(); console.loga(d); 打印出来的是日期格式。
GMT意为格林威治实践,是世界标准时间。GMT+0800(中国标准时间)。
还可以打印毫秒 console.log(d.valueOf( )); 这里的毫秒指的是距离1970-1-1相差的毫秒数,之前为负数,之后为正数。
1.空构造函数 获取的是当前的时间对象
var d = new Date(); console.log(d); //打印的是日期 console.log(d.valueOf()); //打印的是毫秒数
2.构造函数中传入毫秒值
var d = new Date(1548225896561); console.log(d); //根据毫秒值打印对应毫秒值的日期
3.可以传入日期形式的字符串
var d = new Date('2019-12-20 12:20:42'); console.log(d); //根据传入的日期输出对应的毫秒值
4.可以传入数字
var d = new Date(1959, 3, 24); console.log(d); //都为打印当前日期的毫秒值 console.log(d.valueOf());
如何获取日期对象的毫秒值
//方法一 var d = new Date(); console.log(d.valueOf()); //作用和getTime()一样,但是valueOf()系统会自动调用,所以一般不用 console.log(d.getTime()); //作用和valueOf()一样 //方法二 var num = Date.now(); //使用的是静态成员,但这里会出现浏览器不兼容问题,因为它是H5之后新增的 console.log(num); //方法三 var num = + new Date(); //这里的+是取正的意思,数学里的运算符,会自动把日期转换为毫秒数 console.log(num);
日期格式化方法
日期格式化方法 | 含义 |
toString() | 转换成字符串(即日期为黑色字体的字符串) |
valueOf() | 获取毫秒值 |
toDateString() | 这四种为格式化日期方法,在不同的浏览器可能表现不一致,一般不用。前面两个是英文式日期显示,后面两个是使用人本地的日期显示格式,但不同浏览器显示有区别,如2019年12月20日、2019/12/20等 |
toTimeString() | |
toLocalDateString() | |
toLocalTimeString() |
获取日期指定部分
获取日期指定部分 | 含义 |
getTime() | 返回毫秒数和valueOf()结果一样 |
getMilliseconds() | 返回微秒数 |
getSeconds() | 返回秒数0-59 |
getMinutes() | 返回分钟数0-59 |
getHours() | 返回小时0-23 |
getDay() | 返回星期几(注意周日为0周一为1) |
getDate() | 返回当月的第几天 |
getMonth() | 返回月份(注意是从0开始) |
getFullYear() | 返回四位数的年份,如2020 |
案例格式化日期对象(输出想要的格式日期)
写一个函数,格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
function formatDate(date) { //判断参数date是否是日期对象 instanceof instanceof实例(对象)的意思 of的 //console.log(date instanceof Date); if (!(date instanceof Date)){ console.error('date不是日期对象') return; } var year = date.getFullYear(), month = date.getMonth() + 1, //因为getMonth()方法中获取的月份是从0开始 day = date.getDate(), hour = date.getHours(), minute = date.getMinutes(), second = date.getSeconds(); month = month < 10 ? '0' + month : month; //三元运算符,小于两位数的前面补0 day = day < 10 ? '0' + day : day; hour = hour < 10 ? '0' + hour : hour; minute = minute < 10 ? '0' + minute : minute; second = second < 10 ? '0' + second : second; return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second; } var d = new Date(); var dateStr = formatDate(d); console.log(dateStr); var e = new Date(2020,5,9); var datestr1 = formatDate(e); console.log(dateStr1); //输出的是2020-05-05 00:00:00
案例二计算时间差,返回相差的天/时/分/秒,类似倒计时
分析
- 两个日期对象如何相减? var d1 = new Date(); var d2 = new Date(2020,5,9); console.log( d2 - d1); 其实两个日期对象时可以直接相减的,因为相减的过程中自动调用了valueOf()输出了总毫秒数,因此是两毫秒数相减。
- 函数如何返回多少个值? function fn() { return{ year: 1, day:2,hour:3 }; }
- 如何计算相差的天/时/分/秒 由前面相减知道了相差的总毫秒数,则用毫秒数除以对应的倍数即可得出想要的答案
function gerInterval(start,end) { //两个日期对象相减的毫秒数,系统自动调用valueOf() var interval = end -start; //定义变量来存储对应的天时分秒 var day, hour, minute, second; interval /= 1000; //简化interval,因为天时分秒都要除以1000,所以将毫秒转化为秒数 day = Math.round(interval / 60 / 60 /24); //调用Math.round()方法将小数点四舍五入 hour = Math.round(interval / 60 / 60 % 24); minute = Math.round(interval / 60 % 60); second = Math.round(interval % 60); return { day: day, hour: hour, //返回多个值的做法,第一个day是属性,第二个是值或变量。键值对形式 minute: minute, second: second } } var d1 = new Date(); var d2 = new Date(2020,5,9); var birth = getInterval(d1, d2); console.log(birth);
内置对象的Array对象
创建数组对象有两种方式:
- 通过数组字面量创建 [ ] 如: var array = [ ];空数组 var numbers = [4, 9, 56];
- 通过数组的构造函数Array创建。 如: var array = new Array(); 空数组 var num = new Array(6, 9, 21);
如何判断一个变量是否是数组对象
方法一:用instanceof判断
//方法一用instanceof function fn(arr) { //判断参数arr是否是数组对象可以用instanceof console.log(arr instanceof Array); //判断后续传进来的实参是否是Array对象或实例 if (!arr instanceof Array){ console.error('参数arr不是数组对象'); //console.error是报错类的输出 return; } }
方法二:用构造函数自带的isArray()方法判断,但是会有浏览器兼容性问题,因为这时H5后新增的
//方法二用构造函数Array自带的isArray()方法判断 if(!Array.isArray(arr)) { console.error('参数arr不是数组对象'); return; }
Array对象常用的方法
都是内置对象自带的方法,调用即可。数组同时也类似栈和队列
操作方式 | 方法 | 含义 |
toString() | 把数组转换成字符串,逗号分隔每一项 | |
valueOf() | 返回数组对象本身 | |
栈操作(先进后出) | push() | 参数可有多个,一次插入数组的最后,返回值是改变后数组的长度 |
pop() | 返回数组的最后一个元素,并且会修改数组的长度 | |
队列操作(先进先出) | push() | 类似栈操作的push() |
shift() | 取出数组中的第一个元素,修改length属性 | |
unshift() | 在数组的最前面插入元素,返回修改后的数组长度 | |
排序方法 | reverse() | 翻转数组,注意:不是在原数组上翻转数组 |
sort() | 默认情况下是对字符编码(ASCII)从小到大来排序,所以默认对数字无效,是在原数组上进行排序 | |
操作方法 | concat() | 把参数拼接到当前数组即把两个数组拼接起来 |
slice() | 从当前数组截取一个新的数组,不影响原来的数组,参数start从0开始,end从1开始,即自定义从原数组的某个位置到某个位置截取一个数组 | |
splice() | 删除或替换当前数组的某些项目,参数start,deleteCount,options(要替换的项目) | |
位置方法 | indexOf()、lastIndexOf() | 如果没有找到返回-1。前者从前往后找后者从后往前找,找到返回1,否则返回-1 |
迭代方法,遍历数组 | every()、filter()、forEach()、map()、some() | 除了for可对数组进行遍历外,还可以使用这些方法,这些方法相对来说简单多了,但是是H5提出来的,以前的浏览器可能不支持 |
join() | 将数组的所有元素连接到一个字符串中。不带参数时作用和toString一样,带参数时,则以参数为分隔符将数组以字符串连接起来 |
sort()排序的使用
sort()排序是在原数组上进行排序的,默认情况下,sort()排序是按照字符编码ASCII来进行从小到大的排序,即默认情况下对数字的大小排序无效,这时我们要自定义排序方法
//对数字进行大小的顺序排序 var arr = [23, 5, 30, 0]; function compare(a, b) { return a - b; //内置对象自带的,a-b表面从小到大排序;反过来b-a是从大到小排序 } arr.sort(compare); //即sort括号里要传入一个函数compare console.log(arr); //上面34567行其实可以简写为 /* arr.sort(function(a,b) { //因为sort括号里需要传入一个函数所以此函数无需有函数名 return a - b; }); console.log(arr); */
//按字符长度进行比较 var arr = ['abc', 'd', 'agagr', 'lf']; arr.sort(function(a,b){ return a.length - b.length; }); console.log(arr);
内置对象之案例
案例一清空数组
var arr = [3, 9, 15,68]; //方式一 arr = []; //直接对数组进行赋值等于空数组 //方式二 arr.length = 0; //将长度赋值为0 //方式三 arr.splice(0, arr.length); //使用内置对象数组提供的方法,第一个参数为从什么位置开始 //第二个参数为删除多少个元素 //推荐使用方式一,代码简洁
案例二将工资数组里超过2000的删除
使用filter()方法,即将指定范围的元素重新放进另一个数组里
var arr = [1500, 6200, 2100, 1000, 1800, 900]; vaar newArray = arr.filter(function(item) { //item就是数组中的每一个元素 return item < 2000; //将数组里小于2000的重新组成一个数组 }) console.log(newArray);
案例三找到数组中出现某个元素的位置
使用数组提供的indexOf()方法,参数为要找的元素的名称
/*var arr = ['f', 'e', 't', 'e', 'p', 'e', 'k']; //从前往后找元素 console.log(arr.indexOf('e')); //但是只能找到一个元素e,如果没有找到元素会返回-1 console.log(arr.indexOf('e', 4)); //第二个参数指设置indexOf查找的开始位置 */ var arr = ['f', 'e', 't', 'e', 'p', 'e', 'k']; var index = -1; do { index = arr.indexOf('e', index + 1); if (index !== -1){ console.log(index); } }while (index !== -1);
基本包装类型
- 简单类型没有属性和方法,对象才有属性和方法,但是某些情况简单类型调用了属性和方法却没有出错,为什么呢?这是因为自动调用了基本包装类型
var s1 = 'abc';
var len = s1.length;
console.log(len); //返回值为3,不是说简单类型没有属性和方法,那么此处为什么没有报错呢?请看下面解释
//s1.length 执行过程
//把基本类型变成基本包装类型,会创建一个对应的临时对象
var _s1 = new String('abc');
var len = _s1.length;
_s1 = null; //创建的临时对象使用完后会销毁
- 基本包装类型:就是把基本类型包装成复杂类型
- 基本包装类型有:String、Number、Boolean,也是构造函数。一般情况下我们不会使用Number和Boolean,因为会产生歧义。
//Number歧义案例
var n1 = new Number('16'); //创建Number的对象,其中PrimitiveValue(原始值)为16
var n2 = Number('16'); //而此处的Number为类型转换的意思,即把字符串'16'转换为数值类型的16
//Boolean歧义案例
var b1 = new Boolean(false);
var b2 = b1 && true;
console.log(b2);
//输出为true,因为隐含的布尔值转换只有五种情况才会为false,0,‘’,Null,undefined,NaN
//而此处的b1为具体的对象,所有为true,所以有歧义
字符串的不可变性
var s = 'abc'. s = 'xxxxxxxxx'; 当声明了一个字符串的值时,它的内存空间就定下来了,当要再次修改字符串的值时内存会不够因此会重新开辟一个内存空间,前面的内存空间就会造成浪费。
- 所以当拼接大量字符串的时候,会出现性能问题,如特别缓慢,因为要开辟大量大量的内存空间,所以避免拼接大量字符串,少量拼接还是可以的
字符串对象的常用方法
所谓字符串可以理解为将字符拼接起来的一个串,所以可以像操作数组一样操作字符串
字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串
方法类别 | 方法名称 | 含义 |
字符方法 | charAt() | 获取指定位置处的字符 |
charCodeAt() | 获取指定位置处的字符的ASCII码 | |
str[ 0 ] | H5,IE8+支持.作用和charAt( )一样 | |
字符串操作方法 | concat() | 拼接字符串,等效于+的拼接,但是+的拼接更常用 |
slice() | 从start位置开始,截取到end位置,end截取不到 | |
substring() | 从start位置开始,截取到end位置,end截取不到 | |
substr() | 从start位置开始,截取length个字符 | |
位置方法 | indexOf() | 返回指定内容在原字符串的位置,只找第一个 |
lastIndexOf | 从后往前找,只找第一个匹配的 | |
去除空白 | trim() | 只能去除字符串前后的空白,中间的空白去除不了,需自己来 |
大小写转换方法 | to(Locate)UpperCase() | 转换成大写 |
to(Locate)LowerCase() | 转换成小写 | |
其他 | search() | 查找字符串中指定的字符串,search()要比 |
replace() | 替换字符串的一部分,只会替换第一个找到的字符串 | |
split() | 以某个符号作为断点来切割字符串 |
案例一截取“我爱中华人民共和国”中的“中华”两个字
var s = '我爱中华人民共和国';
//因为字符串的不可变性,所以都要给修改后的字符串储存在一个变量中
var newStr = s.substr(2,2); //第一个参数为截取的开始位置,第二个参数为截取的长度
console.log(newStr);
案例二“olangodfueoaosood”查找字符串中所有o出现的位置
var s = 'olangodfueoaosood';
//当查找不到的时候返回的是-1
var index = -1;
do {
index = s.indexOf('o', index + 1);
if (index !== -1) {
console.log(index);
}
}while (index !== -1)
案例三把字符串中的所有o替换成!
var s ='olangodfueoaosood';
//replace()方法只会替换第一个找到的字符串
var index = -1;
do {
index = s.indexOf('o', index + 1);
if (index !== -1) {
//替换
s = s.replace('o', '!');
}
}while(index !== -1);
console.log(s);
案例四将字符串中所有的空白都去掉
//trim()方法只可以去掉某个字符串前后的空格
//思路一:可以把字符串中所有的空格 字符串 用replace()替换成‘’空字符串
var s = ' abs i sf sdf fsfd';
var arr = s.split();
console.log(arr.join(''));
案例五判断一个字符串中出现次数最多的字符,统计这个次数
//统计每一个字符出现的次数
var s = 'dfahdjjhdjdjsf';
var ch;
//此字符出现的次数
var num;
//记录字符串中的一个字符出现的次数
var o = {};
for (var i = 0; i < s.length; i++){
var item = s.charAt(i);
if(o[item]) {
//已经有该属性 +1
o[item]++;
}else {
//对象中没有改属性
o[item] = 1;
}
}
//求最大值,并且找到次数最多的字符
//假设最大值是1
num = 1;
for (var key in o) {
if (num < o[key]) {
//最多的次数
num = o[key];
//次数最多的字符
ch = key;
}
}
console.log(num);
console.log(ch);
案例六获取url地址?后面的内容,并修整成键值对的方式
var url = 'http://www.itheima.com/login?name=zs&age=18%a=1&b=2'
//获取url后面的参数
function gerParams(url) {
//获取?后面第一个字符的索引
var index = url.indexOf('?') + 1;
//url中?后面的字符串name=zs&age=18%a=1&b=2
var params = url.substr(index);
//利用&来切割字符串,并存储到一个数组上
var arr = params.split('&');
var o = {}; //声明一个空对象用来存放分割出来的键值对
//数组中每一项的格式 key=value
for (var i = 0; i < arr.length; i++){ //将数组中分割成的字符串遍历找键和值并对应
var tmpArr = arr[i].split('='); //新建数组来存放以=分割后的键和值
var key = tmpArr[0];
var value = tmpArr[1];
o[key] = value;
}
return 0;
}
var obj = getParams(url);
console.log(obj);
console.log(obj.name); //这样组成的对象里的属性值成员将会方便后续的访问
console.log(obj.age);