//内置对象
//javascript对象分为3种:自定义对象、内置对象、浏览器对象 前两种属于JS基础内容,属于ECMAScript;第三种浏览器对象属于JS独有
//内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或者是最基本且必要的功能(属性和方法)
//内置对象最大的优点就是帮助我们快速开发 比如有:Math,Date,Array,String等
//查文档
//通过MDN/W3C来查询(Mozilla开发者网络(MDN)提供了有关开放网络(OpenWeb)的信息,包括HTML、CSS和万维网及HTML5应用的API)
//如何学习对象中的方法:1.查阅方法的功能(比如Math.max()返回最大值) 2.查看参数意义及类型 3.查看返回值的意义及类型 4.通过demo测试
//Math数学对象 它不是一个构造函数,所以不用new,直接使用即可
/* console.log(Math.PI);//属性,返回圆周率
console.log(Math.max(1,99,29));//方法,返回99
console.log(Math.max(1,2,'asd'));//注意,此方法参数类型只能数值,如果包含了其他类型的参数,则返回NAN
console.log(Math.max()); *///注意,如果没有给参数,则返回-ifinity
//案例:利用对象封装自己的数学对象 里面有PI、最大值、最小值
/* var myMath={
PI:3.1415926,
max:function(){
var max=arguments[0];
for(var i=1;i<arguments.length;i++){
if(arguments[i]>max){
max=arguments[i];
}
}
return max;
},
min:function(){
var min=arguments[0];
for(var i=1;i<arguments.length;i++){
if(arguments[i]<min){
min=arguments[i];
}
}
return min;
}
}
console.log(myMath.PI);
var max1= myMath.max(1,3,5,7,8);
var min1=myMath.min(2,4,7,9,0);
console.log(max1,min1);
*/
//绝对值方法
/* console.log(Math.abs(1));//结果为1
console.log(Math.abs(-1));//结果为1
console.log(Math.abs('-1'));//结果还是1 !!!隐式转换 会把字符串型转换为数字型
console.log(Math.abs('asdf')); *///结果为NAN
//三个取整方法
//1.Math.floor()向下取整(往小了取整)
/* console.log(Math.floor(1.1));//1
console.log(Math.floor(1.9)); *///1
//2.Math.ceil() 向上取整(往大了取)
/* console.log(Math.ceil(1.1));//2
console.log(Math.ceil(1.9)); *///2
//3.Math.round() 四舍五入取整
/* console.log(Math.round(1.1));//1
console.log(Math.round(1.9));//2
console.log(Math.round(1.5));//2
console.log(Math.round(-1.1));//-1
console.log(Math.round(-1.5)); *///!!⭐ 特殊: 此处结果为-1 (按道理说应该为-2) 记住: .5是往大了取(1.5取成2 ,-1.5取成-1)
//数学对象随机数方法 Math.random()返回随机的小数 范围在[0,1)左开右闭(也就是能取到0,取不到1)
/* console.log(Math.random()); */
//得到两数之间的随机整数(包含这两个整数)
//公式:Math.floor(Math.random() * (max -min +1))+ min;
//封装到函数里比较方便
/* function getRandom(min,max){
return Math.floor(Math.random() * (max -min +1))+ min;
}
console.log(getRandom(1,99)); //!!!!⭐记住!很重要
//随机点名
var arr=['张三','李四','王二麻子','马赛克','李普'];
console.log(arr[getRandom(0,arr.length-1)]); */ //这里利用了上面写的取两数之间随机整数的函数getRandom();
//案例:猜数字游戏(随机生成一个整数(1~50),输入一个数后输出大了还是小了还是猜中了)只有5次机会
/* function getRandom(min,max){
return Math.floor(Math.random() * (max -min +1))+ min;
}
var num=getRandom(1,50); //先生成了一个数
var i=1;
for(var i=0;i<=5;i++){
var num1=prompt('请猜一猜数是多少?');
if(i<5){
if(num1>num){
alert('你猜大了');
}else if(num1<num){
alert('你猜小了');
}else{
alert('恭喜你猜中了');
break; //别忘了在此处设置退出循环
}
}else{
alert('很遗憾,机会已经用完了')
break;
}
} */
//日期对象 Date() 这是一个构造函数 必须要用new来创建日期对象
/* var arr=new Array();//创建数组对象
var date=new Date();//创建日期对象
console.log(date);//Date();里没有参数返回的是当前系统的当前时间
//也可以给参数 参数常用写法 数字型 2019,10,01 或者是 字符串型 '2019-10-1 8:8:8'//字符串型最常用
var date1=new Date(2019,10,1);
console.log(date1);//返回了2019,11,1 十一月
var date2=new Date('2019-10-1 8:8:8'); //别忘了new
console.log(date2); */ //结果正确
//日期格式化 方法
/* var date= new Date();
console.log(date.getFullYear()); //得到当前年份 2024
console.log(date.getMonth()); //得到当前年份的月份-1(当前月为4月,但此方法返回的月份是0-11,所以返回的要比实际月份小一个月)
console.log(date.getMonth()+1); //+1后 这样返回的就是正确的月份
console.log(date.getDate()); //返回今天是几号 1号
console.log(date.getDay()); //返回今天星期几(0-6)(周一到周六返回的是1-6,但周日返回0)
//写一个中国式日期 年 月 日 星期
var year=date.getFullYear();
var month=date.getMonth() + 1; //别忘了加一哦!!!
var dates=date.getDate();
var arr=['星期日','星期一','星期二','星期三','星期四','星期五','星期六']; //这里我们为了得到最后的星期1变成星期一,声明一个数组存放星期信息,因为getDay()方法得到的是一个数字,所以可以利用数组下标来获取信息,比如得到数字1,就对应arr[1]里的星期一
//因为0代表星期日,所以把星期日写在数组最开头;!!⭐
var day=date.getDay();
console.log('今天是'+year+'年'+month+'月'+dates+'日'+arr[day]); */ //结果为 2024年4月1日星期一 正确
//格式化日期 时分秒
/* var date=new Date();
console.log(date.getHours());//时
console.log(date.getMinutes());//分
console.log(date.getSeconds()); *///秒
/* //封装函数返回 08:08:08格式
function getTimer(){
var time=new Date();
var h=date.getHours();
h= h<10?'0'+h:h; //用三元表达式来实现加0更简单
var m=date.getMinutes();
m= m<10?'0'+m:m;
var s=date.getSeconds();
s= s<10?'0'+s:s;
return h+':'+m+':'+s;
}
console.log(getTimer()); */
//日期对象Date() 获取日期的总的毫秒形式(!!!⭐时间戳(独一无二)):它永远不会重复 距离1970年1月1号到现在过了多少毫秒 1. valueOf();
/* getTime();
var date=new Date();
console.log(date.valueOf());
console.log(date.getTime());
//2.更简单的写法
var date1= +new Date();//这个写法就是表示总的毫秒数 !!!最常用
console.log(date1);
//3.H5新增写法
console.log(Date.now());//注意格式! */
//案例:倒计时
//思路:用时间戳来做,得到的毫秒转换成天时分秒
/* function countTime(time){ //countTime就是倒计时的意思
var nowTime= +new Date(); //Date()里是空的就代表是当前时间的时间戳
var inputTime= +new Date(time); //Date(time)就代表time时间的时间戳,此处为用户会输入的时间的时间戳
var times= (inputTime - nowTime)/1000; //times表示用户输入的时间距离现在还有多少秒,注意!!这里除了1000,表示原来的总毫秒数除了1000变为了秒数 1s=1000ms;
var t=parseInt(times /60/60/24); //从秒数转换为天数 parseInt()是用来返回整数的,此处必须是整数
t=t<10?'0'+t:t; //意思是t小于10就在t前面补0,否则返回原来的t
var h=parseInt(times /60/60%24); //从秒数转换为小时
h=h<10?'0'+h:h;
var m=parseInt(times /60%60); // 从秒数转换为分钟
m=m<10?'0'+m:m;
var s=parseInt(times %60); //从秒数转换为当前时间处于多少秒
s=s<10?'0'+s:s;
return '距离你输入的时间还剩'+t+'天'+h+'时'+m+'分'+s+'秒';
}
var date=new Date();
console.log(date); //打印当前时间做对比
console.log(countTime('2024-4-1 23:59:59'));
*/
//创建数组:var arr1=new Array(2) 表创建了一个长度为2,元素为空的数组 var arr1=new Array(2,3)表示创建了一个含有2和3元素的数组
//检测是否为数组
//1.instanceof 运算符 用来检测是否为数组
/* var arr=[];
console.log(arr instanceof Array);//是数组就返回true,不是就返回false 此处为true
//2.Array.isArray(参数) H5新增的方法 ie9以上才支持
console.log(Array.isArray(arr)); *///返回true
//添加数组元素
//1.push(参数也就是数组元素) 在数组末尾添加一个元素 原数组会发生变化
// var arr=[1,2,3];
// arr.push(4);
// console.log(arr);//[1,2,3,4]
// console.log(arr.push(5));//结果为5 push返回的结果是!!新数组的长度
// console.log(arr.push(6,7));//结果为6
// console.log(arr);
//2.unshift(参数也就是数组元素) 在新数组开头添加一个元素 原数组会发生变化
// console.log(arr.unshift(0)); //结果为4 返回结果为新数组的长度
// console.log(arr); //结果为[0,1,2,3]
//删除数组元素
//1.pop() 在数组末尾删除一个元素,一次只能删除一个元素,无参数 原数组会发生变化
// var arr=['qwe','asd','zxc','ghj'];
// console.log(arr.pop()); //返回ghj 也就是!!被删除掉的那个元素
// console.log(arr); //['qwe','asd','zxc']
//2.shift() 在数组开头删除掉一个元素 无参数 原数组会发生变化
// var arr=['qwe','asd','zxc','ghj'];
// console.log(arr.shift()); //返回qwe 也就是被删除掉的那个元素
// console.log(arr);
//案例:筛选数组[1500,1400,1800,2000,2100](将大于2000的数筛出去,剩余的元素放到一个新数组里)
/* var arr=[1500,1400,1800,2000,2100];
var newArray=[];
for(var i=0;i<arr.length;i++){
if(arr[i]<2000){
newArray.push(arr[i]); //将arr[i]依次追加到新数组里
}
} */
//数组排序
//翻转数组 reverse()
/* var arr=['qwe','asd','zxc','ghj'];
arr.reverse(); //直接用reverse方法就可以实现翻转
console.log(arr); */
//冒泡排序 sort()
/* var arr1=[1,5,3,7,9]; //单个数是没问题的,但多位数时就会有问题,比如(5,11,1,55)结果就是(1,11,5,55)把两位数当成单字符来看,直接将第一位与之匹配
arr1.sort();
console.log(arr1); */
//针对上述多位数问题进行解决 此问题也可以在MDN里面查询
/* var arr1=[1,51,13,71,77];
arr1.sort(function (a,b){ //在sort里加函数
// return a-b; //升序排法
return b-a; //降序排法
})
console.log(arr1); */
//数组索引
//1.indexOf()!!!记住这个即可
/* var arr=['asd','qwe','zxc','ghj'];
console.log(arr.indexOf('asd')); //返回该数组元素的索引号0
var arr1=['asd','qwe','zxc','ghj','asd'];//如果数组有相同元素
console.log(arr1.indexOf('asd')); //返回第一个找到的元素的索引号0
console.log(arr1.indexOf('zso')); */ //如果数组中没有这个元素则返回-1
//lastIndexOf():从数组!后面!开始往前找,其他与indexOf()规则相同
//!!!重点案例⭐:数组去重(面试常考)
//数组['a','d','c','a','c','x','w'],要求去除其中重复的元素(将不重复的放进新数组)
//从上述刚学的数组索引来下手:核心原理:遍历旧数组,用旧数组的元素去新数组里查询,没有就放进新数组,有就略过
//indexOf()利用 有想要查找的元素就返回索引号,没有就返回-1,旧数组去查新数组,没有返回-1就可以存进去
/* function unique(arr){
var newArry=[];
for(var i=0;i<arr.length;i++){
if(newArry.indexOf(arr[i])===-1){//如果第i个元素不在新数组里
newArry.push(arr[i]);//则把这个元素添加进新数组
}
}
return newArry;
}
console.log(unique(['a','d','c','a','c','x','w'])); */ //结果为["a", "d", "c", "x", "w" ]
//数组转换为字符串
//1.toString()
/* var arr=[1,2,3];
console.log(arr.toString()); *///结果为黑色的1,2,3(表示字符串)
//2.join(间隔符)
/* var arr1=['qwe','asd','dgh'];
console.log(arr1.join('-')); //qwe-asd-sgh
console.log(arr1.join('&')); */ //qwe&asd&dgh
//作业:查询concat();splice();slice();方法
//1.concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
//以下代码将两个数组合并为一个新数组:
/* js
const letters = ["a", "b", "c"];
const numbers = [1, 2, 3];
const alphaNumeric = letters.concat(numbers);
console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3] */
/* 以下代码将三个数组合并为一个新数组:
const num1 = [1, 2, 3];
const num2 = [4, 5, 6];
const num3 = [7, 8, 9];
const numbers = num1.concat(num2, num3);
console.log(numbers);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9] */
//2.slice() 方法返回一个新的数组对象,这一对象是一个由 start 和 end 决定的原数组的浅拷贝(包括 start,不包括 end),其中 start 和 end 代表了数组元素的索引。原始数组不会被改变。
//返回现有数组的一部分
/* const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
const citrus = fruits.slice(1, 3);
// fruits 包含 ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus 包含 ['Orange','Lemon']
*/
//3.!!重要!splice() 方法通过移除或者替换已存在的元素和/或添加新元素就地改变一个数组的内容。
//参数
/* start
从 0 开始计算的索引,表示要开始改变数组的位置,它会被转换成整数。
负索引从数组末尾开始计算——如果 start < 0,使用 start + array.length。
如果 start < -array.length,使用 0。
如果 start >= array.length,则不会删除任何元素,但是该方法会表现为添加元素的函数,添加所提供的那些元素。
如果 start 被省略了(即调用 splice() 时不传递参数),则不会删除任何元素。这与传递 undefined 不同,后者会被转换为 0。
*/
//返回值
/*
一个包含了删除的元素的数组。
如果只移除一个元素,则返回一个元素的数组。
如果没有删除任何元素,则返回一个空数组。 */
//移除索引 2 之前的 0(零)个元素,并插入“drum”
/* js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];
const removed = myFish.splice(2, 0, "drum");
// 运算后的 myFish 是 ["angel", "clown", "drum", "mandarin", "sturgeon"]
// removed 是 [],没有元素被删除 */
//在索引 3 处移除 1 个元素
/* js
const myFish = ["angel", "clown", "drum", "mandarin", "sturgeon"];
const removed = myFish.splice(3, 1);
// 运算后的 myFish 是 ["angel", "clown", "drum", "sturgeon"]
// removed 是 ["mandarin"] */
//字符串对象
/* var arr='andy';
console.log(arr.length); */ //思考:arr是一个普通数据类型,为何可以有length属性呢?(只有复杂数据类型才会有属性和方法)
//1.基本包装类型:把简单数据类型包装为复杂数据类型 这样简单数据类型就可以使用属性和方法了
//2.字符串不可变
/* var str='andy';
str='red';
console.log(str); */ //结果为red(看起来好像是str改变了,其实并没有,只是后来的red是重新申请的内存空间,然后str又指向了red罢了,说明andy还是存在,如果过多这样拼接字符串,会浪费空间)
//根据字符返回位置(字符串的所有方法都是不会改变字符串本身的,操作完成会得到新的字符串)
//1.indexOf()
//2.lastIndexOf()
//根据字符返回对象 str.indexOf('要查找的字符',[起始位置])
/* var str='你好我是张三,你好不好?';
console.log(str.indexOf('好',2)); */ //结果为8(从索引号为2的元素查起)
//案例:返回字符位置
//查找字符串'abcoesfozzopp'中出现的o的位置以及出现次数 !!!经典面试题⭐
//核心算法:先查找第一个'o'的位置,只要indexOf返回的不是-1就继续往后查找,因为indexOf只能查找到第一个出现的位置,所以后面的查找要改变索引,让indexOf从查找到后的后一个开始查找,也就是查找到后的当前索引加一再继续查找
//
/* var str='abcoesfozzopp';
var index=str.indexOf('o');
console.log(index); //3
var sum=0;
while (index!==-1){ //只要indexOf返回的不是-1就继续往后查找
console.log(index);
sum++;
index = str.indexOf('o',index+1); //让indexOf从查找到后的后一个开始查找,也就是查找到后的当前索引加一再继续查找
}
console.log('次数为'+sum); //次数为3 */
//课后作业:['red','blue','red','green','pink','red'],求red出现的位置及次数
/* var str=['red','blue','red','green','pink','red'];
var sum=0;
index=str.indexOf('red');
while (index!==-1){
console.log(index);
sum++;
index=str.indexOf('red',index+1);
}
console.log(sum); */
//根据位置返回字符!!!⭐重点
//charAt(index) index就是索引
/* var str='andy';
console.log(str.charAt(1)); */ //1
//遍历所有字符
/* for(var i=0;i<str.length;i++){
console.log(str.charAt(i));
} */
//charCodeAt(index)返回ASCII码 这个在实际开发中可以判断用户按了哪个键,比如a-96
/* console.log(str.charCodeAt(0)); */ //97
//str[index] H5新增
/* console.log(str[0]); */
//案例:判断字符串'abcoesfozzopp'中出现次数最多的字符,并统计次数
//核心算法:利用charAt()遍历字符串,把每个字符取出来存储给某个对象,如果对象没有该属性则为1,如果存在就加1
/* var str='abcoesfozzopp';
var o={};//声明一个对象
for (var i=0;i<str.length;i++){
var chars = str.charAt(i);
if( o[chars]){ //判断o对象里有没有chars属性值,chars就是str里的每个字符
o[chars]++;
}else{
o[chars]=1; //如果没有就为1
}
}
console.log(o); //Object { a: 1, b: 1, c: 1, o: 3, e: 1, s: 1, f: 1, z: 2, p: 2 }
//遍历对象 for in
var max=0;
var ch='';
for (var k in o){
if(o[k]>max){
max=o[k]; //o[k]是属性值
ch=k; //k是属性名,上面写的给对象存储字符里的字符就是此处的属性名
}
}
console.log(ch);
console.log(max); */
//字符串操作方法(重点!!⭐)
//concat(str1,str2,······)将多个字符串拼接起来,等效于+,但+更常用
/* var str1='abdy';
console.log(str1.concat('red')); //abdyred */
//substr('截取的起始位置','截取几个字符')
/* var str='改革春风吹满地';
console.log(str.substr(2,2)); //春风 第一个2是指从2位置开始截取,第二个2是指截取两个字符 */
//替换字符 replace('被替换的字符','替换为的字符')
/* var str='andy';
console.log(str.replace('a','b')); //bndy
var str1='andyandy';
console.log(str1.replace('a','b')); //bndyandy !!注意:此处replace只能替换第一个字符,无法替换多个相同的字符
//解决办法,利用循环
var str2='andyandyaa'
while(str2.indexOf('a') !==-1){ //str.indexOf('a')返回a的位置,如果最后返回值为-1则表示差不到a了,此时就能结束循环
str2 = str2.replace('a','b'); //str2替换一次过后又赋值给str2,新的str2第一个a已经被替换掉了,则再次循环查找到的a则是后面的第二个a
}
console.log(str2); //bndybndybb */
//字符转换为数组 split('分隔符') 前面学过join('分隔符')是把数组转换为字符串
/* var str='red&blue&pink';
console.log(str.split('&')); //Array(3) [ "red", "blue", "pink" ] */
//课后查阅:toUpperCase() :String 的 toUpperCase() 方法将该字符串转换为大写形式。 toUpperCase() 方法返回将字符串转换为大写形式后的值。由于 JavaScript 中的字符串是不可变的,因此此方法不会影响字符串本身的值。 console.log("alphabet".toUpperCase()); // 'ALPHABET' const sentence = 'The quick brown fox jumps over the lazy dog.'; console.log(sentence.toUpperCase()); // Expected output: "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."
//toLowerCase(): String 的 toLowerCase() 方法将该字符串转换为小写形式。 console.log("ALPHABET".toLowerCase()); // 'alphabet' const sentence = 'The quick brown fox jumps over the lazy dog.'; console.log(sentence.toLowerCase()); // Expected output: "the quick brown fox jumps over the lazy dog." toLowerCase() 方法返回将字符串转换为小写形式后的值。toLowerCase() 不会影响字符串 str 本身的值。
//课后作业:字符串:'abaasdffggghhjjkkgfddssss3444343':字符串长度、取出指定位置字符0,3,5,9、查找指定字符i,c,b是否在字符串中存在、替换指定字符g-22,s-b、截取1-5的字符串、找出以上字符串中出现次数最多的字符位置及次数
/* var str='abaasdffggghhjjkkgfddssss3444343';
console.log(str.length); //字符长度32
console.log(str.charAt(0));
console.log(str.charAt(3));
console.log(str.charAt(5));
console.log(str.charAt(9)); //0,3,5,9返回字符aadg
console.log(str.indexOf('i')); //-1 没有
console.log(str.indexOf('c')); //-1 没有
console.log(str.indexOf('b')); //1 有,且索引号为1
while(str.indexOf('g') !==-1){
str = str.replace('g',22);
}
while(str.indexOf('s') !==-1){
str = str.replace('s','b');
}
console.log(str); //abaabdff222222hhjjkk22fddbbbb3444343(被替换之后的字符串)
console.log(str.substr(1,5)); //baabd(已经被替换过后的字符串截取出来的1-5的字符)
var ob={};
for (var i=0;i<str.length;i++){
value=str.charAt(i);
if (ob[value]){
ob[value]++;
}else{
ob[value]=1;
}
}
var max=0;
var ch='';
for(var k in ob){
if(ob[k]>max){
max=ob[k];
ch=k;
}
}
console.log(max,ch); //8 2 */
//Javascript的简单数据类型和复杂数据类型
//简单数据类型:又叫基本数据类型或者值类型,在存储变量时存储的时值本身,因此叫值类型(string、number、boolean、undefined、null ;注意!!使用null时,null返回的是object也就是一个空的对象,在实际开发中,如果想要使用对象却还没想好放什么时可以先定义为null)
//复杂数据类型:又叫做引用类型,在存储时变量中存储的仅仅是地址(引用),因此叫引用数据类型 (通过new关键字创建的对象(系统对象,自定义对象),如:Object、Array、Date等)
//堆和栈(Javascript中本没有堆栈的概念)
//栈:由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈; !简单数据类型存放在栈里面
//堆:存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收; !复杂数据类型存放到堆里面
//!!⭐面试常考:简单数据类型的内存分配 : 存放在栈里,直接在栈里面开辟一个空间存放值
//复杂数据类型的内存分配 : 首先在栈里面存放地址(十六进制表示),然后这个地址指向堆里面的数据(也就是说真正的对象实例存放在堆空间中)
//简单数据类型传参:函数的形参也可以看成一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实时把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量
//复杂数据类型传参:函数的形参也可以看成一个变量,当我们把一个引用类型变量传给函数的形参时,其实时把变量在栈空间里的地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象 以下👇为例子说明
/* function Person(name){
this.name=name;
}
function f1(x){ //x=p(将p存放的地址复制给了x)
console.log(x.name); //刘德华
x.name='张学友'; //将name改了,原本的刘德华改成了张学友
console.log(x.name); //张学友
}
var p=new Person('刘德华');
console.log(p.name); //刘德华
f1(p);
console.log(p.name); //张学友 */