学习Java Script的第二周

96 阅读12分钟

数组的基础

创建数组

  1. 直接量:var arr=[值1,....];
  2. 构造函数:var arr=new Array(值1,....);

hash(关联)数组:下标是可以自定义的

为什么要用hash数组:因为索引数组的小标无具体的意义,不便于查找
如何使用:

1、创建:2步
  1. 先创建一个空数组:var arr=[];
  2. 为数组添加自定义下标并且赋值:arr["自定义下标"]=新值;
2、访问

arr["自定义下标"];

3、强调:

hash数组的length会失效,永远为0.
遍历hash数组,不能再使用for循环了,必须使用for in循环. 语法:
for(var i in arr){
i->下标
arr[i]->当前次元素
}

4、hash数组的原理

hash算法:

  1. 将字符串,计算出一个尽量不重复的数字(地址值)
  2. 如果字符串内容相同,则计算出来的数字也一定相同
  3. 添加元素:js解释器会将自定义下标交给hash算法,得到一个数字(地址值),直接将你要保存的数据放到此地址之中保存。
  4. 获取元素:js解释器会将指定的下标再次交给hash算法,得到了一个和当初保存时完全一样的数字(地址值),通过此地址值就可以找到当初保存的数据了,取出来使用
5、拓展

JS里面一切东西都是对象,万物皆对象,除了undefined和null,【一切对象的底层都是hash数组】

数组的API

1、arr to str:
  1. var str=arr.join("自定义连接符");
  2. 固定套路:2个:
    1、将数组里面的内容拼接为一句话/单词 - 无缝拼接,其实就是拼接了一个空字符串
    2、将数组拼接为DOM页面元素
    var arr=["-请选择-","北京","南京","西京","东京","重庆"];
    var str=""+arr.join("")+"";
    sel1.innerHTML=str;
2、拼接数组:添加元素的新方式

语法:var newArr=arr.concat(新值1,arr1,...);
将传入的实参全部拼接到数组的尾部。
特殊:

  1. 不修改原数组,只会返回一个新数组
  2. concat支持传入数组参数,悄悄将的你传入的数组打散为单个元素再拼接
3、截取子数组:只想要取出数组的某一部分使用

根据你传入的开始下标一直截取到结束下标
语法:var subArr=arr.slice(starti,endi+1)
特殊:

  1. 不修改原数组,只会返回一个新数组
  2. 含头不含尾
  3. endi可以省略不写,如果不写,则从starti截取到末尾
  4. starti和endi都可以省略不写,那么从头到尾完整的赋值一份,此操作也叫做深拷贝!复制了一个副本给对方,两者不会相互影响
  5. 支持负数参数,-1代表倒数第一个
4、删插替:

删除:var dels=arr.splice(starti,n); n代表你要删除几个.删除的数据有一个返回值,如果要用的话可以用一个数组将其装住。

插入:var dels=arr.splice(starti,0,新值1,...);
特殊:

  1. 原starti位置的元素以及后续元素都会被向后移动
  2. 尽量不要插入一个数组,会导致我们的数组一些是一维,一些是二维,导致遍历的时候极不方便

替换:var dels=arr.splice(starti,n,新值1,...); 插入的元素和删除的元素,个数不必相等

5、翻转数组:arr.reverse();
6、数组的排序

数组的API:arr.sort();
默认:将数组中的元素转为字符串,然后再按位PK每个字符的unicode号(ASCII码)
1、希望按照数字升序排序:
arr.sort(function(a,b){
return a-b;})//a是后一个元素,b是前一个
2、希望按照数字降序排序:
arr.sort(function(a,b){
return b-a;})

7、栈和队列:添加元素和删除元素的新方式

栈:其实就是数组,只不过是一端封闭,只能从另一端进出

  1. 开头进:arr.unshift(新值1,...);//添加元素的新方式,向前添加,缺点:导致其他元素的下标都会发生变化
  2. 开头出:var first=arr.shift();//删除元素的新方式,向前删除,一次只能删除一个,也有返回值,返回的是删除的那个元素,缺点:导致其他元素的下标都会发生变化
  3. 结尾进:arr.push(新值1,...);//添加元素的新方式,向后添加
  4. 结尾出:var last=arr.pop();//删除元素的新方式,向后删除,一次只能删除一个,也有返回值,返回的是删除的那个元素

队列:其实就是数组,只不过只能从一端进入,从另一端出去

  1. 开头进:arr.unshift(新值1,...);//添加元素的新方式,向前添加,缺点:导致其他元素的下标都会发生变化
  2. 结尾出:var last=arr.pop();//删除元素的新方式,向后删除,一次只能删除一个,也有返回值,返回的是删除的那个元素
  3. 结尾进:arr.push(新值1,...);//添加元素的新方式,向后添加
  4. 开头出:var first=arr.shift();//删除元素的新方式,向前删除,一次只能删除一个,也有返回值,返回的是删除的那个元素,缺点:导致其他元素的下标都会发生变化
8、新的6组API:
1、判断:2个,判断的结果一定是一个布尔值
  1. every:每一个,要求所有的元素都满足条件,结果才为true,只要有一个不满足则为false,非常类似于我们以前学的&& var bool=arr.every(function(val,i,arr){return})
  2. some:有一些,要求只要有一个元素满足,则为true,全部不满足才为false,非常类似于我们以前学的|| var bool=arr.some(function(val,i,arr){return 判断条件;})
2、遍历:拿到数组中的每个元素做相同 或 相似的操作
  1. forEach - 直接修改原数组: arr.forEach(function(val,i,arr){操作})
  2. map - 不修改原数组,返回一个新数组
  3. var newArr=arr.map(function(val,i,arr){return 操作;})
3、过滤和汇总:

过滤:筛选出你需要的部分,但是和现实不太一样,原数组是不会变化的! var subArr=arr.filter(function(val,i,arr){return 判断条件;}) 汇总: var sum=arr.reduce(function(prev,val,i,arr){return prev+val;})

9、箭头函数,专门简化一切的匿名回调函数:

公式:function去掉,()和{}之间添加一个=>,如果形参只有一个,那么()可以省略,如果函数体只有一句话,那么{}省略,如果函数体只有一句话并且是return,那么return和{}一起省略

2、二维数组:数组的元素,又引用着另一个数组

创建: var arr=[ ["",,], ["",,], ["",,]];
访问:arr[行下标][列下标];

2、String的概念:

什么是字符串:多个字符组成的【只读】字符【数组】 、字符串中的个数:

  1. str.length;
  2. 获取字符串中的某个字符:str[i];
  3. 遍历字符串
  4. 所有数组不修改原数组的API,字符串也可以使用(concat、slice)

2、StringAPI:

1、转义字符:\
  1. 将字符串中和程序冲突的字符转为原文""" '''
  2. 包含特殊功能的符号换行:\n制表符:\t 大空格,跟敲tab效果是一样的
  3. 输出unicode编码的字符
    汉字的第一个字:\u4e00 -> ascii码:19968
    汉字的最后一个字:\u9fa5 -> ascii码:40869
2、大小写转换:将字符串中每个英文字符统一的转为大写 或 小写

var 大写=str.toUpperCase();
var 小写=str.toLowerCase();

3、获取字符串中的指定位置的字符:str.charAt(i) === str[i]
4、获取字符串中的指定位置的字符的ASCII码:

var ascii=str.charCodeAt(i);
通过ASCII码转回原文
var 原文=String.fromCharCode(ascii);

5、检索字符串:检查索引 - 检查下标,获取关键字的下标

var i=str/arr.indexOf("关键字",starti); 用来判断数组内有没有这个关键字,只关心反不返回-1.

6、拼接字符串:var newStr=str.concat(新字符串,...) === 还不如+运算
7、截取字符串:3个
  1. var newStr=str/arr.slice(starti,endi+1);//和数组的用法一模一
  2. str.substring(starti,endi+1);//几乎和slice一样,但是不支持负数参数
  3. str.substr(starti,n);//n代表截取的个数,不必考虑含头不含尾
8、替换字符串

var newStr=str.replace("固定关键字"/RegExp,"新内容")

9、去掉开头结尾的空白字符
  1. str.trim();开头结尾
  2. str.trimStart();开头
  3. str.trimEnd();结尾
10、切割/分割字符串
  1. 作用:将字符串切割为数组:str<=>arr
  2. var arr=str.split("自定义切割符");
  3. 特殊:
    1、切割后,切割符就不存在了
    2、如果你的切割符写的就是一个空字符串"",切散每一个字符

Math对象:专门提供了数学计算的API

  1. Math不需要创建,直接使用,由浏览器的JS解释器自动创建
  2. API:
    上取整:Math.ceil(num);
    下取整:Math.floor(num);
    四舍五入取整:Math.round(num); 其他取整:parseInt(str)+num.toFixed(d);
num.toFixed(d);
  1. d代表保留的小数位数,而且也带有四舍五入的功能
  2. 解决浏览器带来的舍入误差,计算机很笨,但是他的记忆力很强,而且速度很快,笨在何处?比如:2-1.6===0.3999999999999
  3. 返回的结果是一个字符串,建议搭配parseFloat使用
乘方和开方
  1. 乘方:Math.pow(底数,幂) === ES9提供了简化:底数**幂
  2. 开方:Math.sqrt(num);//只能开平方
最大值和最小值
  1. var max/min=Math.max/min(a,b,d,c,e,f,g...);自动在你传入的数字中找到最大值或最小值。
  2. 不支持数组参数
    解决方法:Math.max/min.apply(Math,arr);//apply具有打散数组的功能
绝对值:把负数变成整数

Math.abs(num)

随机数:Math.random(); - 在0~1之间取一个随机小数

公式:parseInt(Math.random()*(max-min+1)+min);

Date对象

1、创建
  1. 创建当前时间:var now=new Date();
  2. 创建一个自定义时间:var birth=new Date("yyyy/MM/dd hh:mm:ss");创建一个自定义时间:
  3. var birth=new Date(yyyy,MM-1,dd,hh,mm,ss);//修正月份,从0~11月,0代表1月
  4. 复制一个日期:为什么:日期的所有的API都是直接修改原日期的,无法获得修改之前的日期所以,在执行API之前都要先进行一次复制,然后再操作复制后的日期var end=new Date(start);
2、操作
  1. 两个日期对象之间可以相减,得到一个毫秒差(大-小),换算出自己想要的任何一部分 - 日期的本质其实就是保存了一个毫秒数(做出倒计时的关键
  2. API:
    年月日星期:FullYear Month Date Day
    时分秒毫秒:Hours Minutes Seconds Miiliseconds 每一个分类都有一对getXXX/setXXX
  3. 取值范围:日期还会自动进制 FullYear - 当前年份的数字Month - 0-11 Date - 1-31Hours - 0-23 Minutes、Seconds:0-59Day:0~6,0代表星期天 任何人都可以set,唯独Day没有set操作
  4. 如果希望对某个分类进行加减操作的话date.setXXX(date.getXXX()+/-n)
  5. 格式化日期为本地字符串:date.toLocaleString();
3、定时器:
  1. 周期性定时器:每过一段时间就会执行一次,先等再做,会反复执行,需要自己写停止才能停止 开启:timer=setInterval(callback,间隔毫秒数); 停止:clearInterval(timer);
  2. 一次性定时器:等待一段时间,执行一次就结束了
    开启:timer=setTimeout(callback,间隔毫秒数); 停止:clearTimeout(timer);

扩展:如何使用JS创建页面元素:3步 - 深入数据渲染

  1. 创建空标签:var elem=document.createElement("标签名");
  2. 为其设置必要的属性和事件 elem.属性名="属性值"; elem.on事件名=function(){}
  3. 渲染到DOM树 - 上树 父元素.appendChild(elem);

BOM:Browser Object Model:浏览器对象模型

BOM的所有东西,都不需要创建,直接使用,浏览器的JS解释器会自动创建

window对象:扮演着两个角色:一个页面只有一个window

代替全局对象global,保存着全局变量和全局函数

属性:

  1. 获取浏览器的完整大小:outerWidth/outerHeight;
  2. 获取浏览器的文档显示区域(用户能看到的部分)的大小:innerWidth/innerHeight;
  3. 获取屏幕的完整大小:screen.width/height;

方法:

  1. 当前窗口打开,可以后退
    HTML:用A标签
    JS:open("url","_self");

  2. 当前窗口打开,禁止后退
    history:【当前窗口】的历史记录(打开过的url),他其实可以做的事儿就是前进和后退
    location:【当前窗口】的正在打开的url,而他有一个API: location.replace("新url");//叫做替换,不叫作跳转,是不会产生历史记录的,自然也就不能后退前进

  3. 新窗口打开,可以打开多个
    HTML:用A标签
    JS:open("url","_blank")

4.新窗口打开,只能打开一个
HTML:用A标签,将"traget写为自定义name"
JS:open("url","自定义name")

打开新窗口/新链接

var newW=open ("url","target","width=?,height=?,left=?,top=?");

  1. 如果你没有传入第三个参数,那么窗口会和浏览器融为一体,浏览器多大,窗口就多大
  2. 如果你传入了第三个参数,那么窗口会和浏览器分离开,独立存在
  3. 可以拿个变量保存住此窗口,以后用于其他操作
关闭窗口:window/newW.close();
改变新窗口的大小:newW.resizeTo(新宽,新高);
改变新窗口的位置:newW.moveTo(新x,新y);
window还提供了三个弹出框:但是具有兼容性问题
  1. 警告框:alert("警告文字");
  2. 输入框:var user=prompt("提示文字");
  3. 确认框:var bool=comfirm("提示文字");
window的专属事件:
  1. window.onload - load:加载,等待其他所有的资源加载完毕后才会执行的代码
  2. window.onresize - 创建如果大小发生了变化,就会触发,搭配上上面的innerWidth,我就可以判断现在窗口的大小不同,做不同的操作也就是响应式布局
  3. window.onscroll - 滚动事件,一旦滚动就会触发

获取滚动条当前的位置:window.scrollY
获取元素举例页面顶部有多远:elem.offsetTop/offsetLeft

本地/客户端存储技术:

cookie:存储大小只有2kb,最多只能保存30天
webStorage:存储大小只有8mb,可以永久保存

  1. sessionStorage - 会话级,只要浏览器一旦关闭,数据就会死亡
  2. localStorage - 本地级,只要你不清空他,他就永久存在

操作:

  1. 添加:xxxStorage.属性名="属性值";
  2. 读取:xxxStorage.属性名;
  3. 删除:xxxStorage.removeItem("属性名");
  4. 清空:xxxStorage.clear();