数组的基础
一. 数组创建方法上的区别 ( 填坑 )
1. 创建数组:
(1). 直接量方式 : var arr = [ 值1 , 值2 , 值3 .... , 值n ] ;
(2). 构造函数方式 : var arr = new Array(值1 , 值2 , 值3 .... , 值n);
//若只传入一个数字 , new Array(num); 定义成一个 length 为 num 的 空数组 , 里面有无数的undefined(下标越界);
2. 按值传递 : ( 面试题 )
(1). 原始值类型 :
复制了一个副本传递给别人 , 两者原本的值互不影响
var a = 1;
var b = a; //a复制了一个副本传递给b
//情况1 : a++; ==> a=2;
b=1;//b等于原来的副本,并不改变
//情况2 : b++: ==>
(1). 引用对象类型 :
复制了一个地址值传递给别人( 浅拷贝 ) , 因为引用类型很大 , 不能把内容保存在变量本地 , 而是只保存了地址值 , 当两者共用一个地址 ,其中一个改变了地址中存储的数据 , 另一个变量取到的值也随之发生变化
var Tom = ["包子1","包子2","包子3","包子4"];
var Jerry = Tom ;
Tom.lenght--; //Tom吃一个包子, 笼里就少一个 ,Tom/Jerrry = ["包子1","包子2","包子3"]
Jerry.lenght--; //Jerry吃一个包子, 笼里又少一个 ,Jerrry/Tom = ["包子1","包子2"]
** 如何释放引用类型?
一定要数清楚有几个变量引着这个引用类型 , 每个变量都要释放 , 这个引用类型才能释放干净 ;js底层有一个垃圾回收器 , 只有垃圾计数器为 0 时 , 才会删除这条数据 ;
** 所以建议代码都封装成函数 , 因为函数运行结束之后一切变量都会自动释放;
二 . hash数组 (关联数组)
数组:
1. 索引数组 :
下标都由数字组成 (0 - arr.length) , 下标无具体含义 , 实际使用起来不便于查找 ;
2. hash数组 :
可以自定义下标 , 下标语义化 , 实际使用方便查找
1. 创建哈希数组
(1) . 创建一个空数组:var arr = [ ];
(2) . 为数组添自定义下标:arr [“自定义下标”] = 值 ; 如 arr [“红烧肉”] = "48元";
2. 访问数组元素
arr [“自定义下标”] ;
3. 特殊
因为下标被自定义了 , 不再是数字 , 故哈希数组的 length属性失效永远为0;
所以不能再用for循环来遍历数组 , 要用 for in , 不限定循环条件和次数 , 为了遍历哈希数组存在;
for ( var i in arr){
console.log(i); //当前次下标
console.log(arr[i]); //当前次元素
}
4. 哈希数组的原理
利用哈希算法 , 将字符串计算出一个尽量不重复的数字作为地址值 , 同一个字符串计算出来的数字一定相同 ;
三. 二维数组
1. 定义 :
数组的元素又引用着另一个数组; 何时使用 : 一个数组里的元素希望再分类
2. 创建二维数组 :
var arr=[ ["红烧肉","48元","一碗"],
["黄焖鸡","38元","一碗"],
["三杯鸡","38元","一碗"]
];
4. 访问 :
arr [ 行下标 ][ 列下标 ];
5. 特殊
列下标越界 , 返回undefined;
行下标越界 , 报错 , 因为行下标越界已经返回了一个undefined , undefined不可以再取列下标
四. 数组 Array --- API
API : 前辈们定义了很多方法 , 让我们可以直接使用 , 而不需要访问源码
ES3提供的数组API
1. 数组转字符串 --> arr.join("自定义连接符");
-
语法 :
var str = arr . join ("自定义连接符") ; -
固定套路 :
( 1 ) 数组内元素无缝拼接var arr = "h","a","p","p","y"]; var str = arr.join(""); console.log (str) ; //输出字符串happy( 2 ) 数组元素拼接为页面元素 ---> 初见数据渲染页面
var arr = ["-请选择-","北京","南京","云南"]; var str = "<option>"+arr.join("</option><option>")+"</option>"; sel.innerHTML = str; //上树 --> <select id="sel"></select>
2. 数组拼接 ---> arr.concat(新值1,...);
- 语法 :
var newArr = arr.concat(新值1,数组2,...新值n); - 注意 :
concat 可以传入数组参数,但会打散后再拼接 , 要直接写作[ ]形式;
3. 截取子数组 ---> arr.slice(starti,endi);
slice ---> 片
-
语法 :
var subArr = arr.slice(starti,endi); -
注意 :
(1) endi可以省略 , 默认从starti截取到数组结束
(2) endi和starti都省略 , 默认从头到尾复制一份完整的副本给subArr ; ---> 深拷贝
(3) 支持传入负参数,代表倒数第几个 ; ---> -1就是倒数第一个
------以上API不改变原数组返回修改后的新值 , 以下API会改变原数组------
4. 删除 / 插入 / 替换 ---> arr.splice();
splice ---> 拼接
-
删除:
var dels = arr.splice(starti,n);
//n -->删除个数 , dels 接住的是被删除的元素组成的数组 , 没删除东西也会返回一个空数组 -
插入:
arr . splice (starti , 0 , 值1,值2.....);
//n=0 , 删除0个 , 但在starti后面插入新的数组元素
//splice插入数组元素不会打散,会导致数组里有些一维数组 -
替换:
var dels=arr.splice(starti,n,值1,值2,....值n);//删除的个数和插入的个数不必一致
5. 翻转数组 ---> arr.reverse();
6. 数组排序 ---> arr.sort();
-
语法 :
arr.sort();
//默认将arr中的元素逐一转为字符串 , 按照ASCII码/Unicode码来按位pk
//出现这样的情况 : [22, 333, 36, 37, 456, 65, 98] -
数字按升序排列
arr.sort ( function ( a,b ) { // a --> 前一位数字 b --> 后一位数字 return a-b; // a-b > 0 ab前后交换 //a-b <= 0 ab位置不变 }); //匿名回调函数 , sort方法内部已调用 -
数字按降序排列
arr.sort ( function ( a,b ) { // a --> 前一位数字 b --> 后一位数字 return b-a; });
7. 栈和队列 (本质是数组 , 提供了删除/插入的方法)
- 栈: 先进后出 ,一端封闭 , 一端进出 ;
- 队列: 先进先出, 一端进 , 另一端出 ;
- API: //可以插入/删除多个参数,数组也行,但是不建议
| 进 (插入) | 出 (删除) //变量接住的是被删除的部分 | |
|---|---|---|
| 开头 | arr . unshift ( ); | var first = arr . shift( ); |
| 结尾 | arr . push( ); | var last = arr . pop( ); |
ES5提供的数组API (三组,6个)
1. 判断
( 1 ) . arr . every( );
//相当于&&号,全真为真 ,一假为假 ;
var bool = arr . every(function(val ,i, arr){ //value:当前值 i:下标 arr:原数组
return 判断条件; //返回一个bool值
});
( 2 ) . arr . every( );
//相当于||号,一真为真 ,全假为假 ;
var bool = arr . some(function(val ,i, arr){ //value:当前值 i:下标 arr:原数组
return 判断条件; //返回一个bool值
});
2. 遍历
//拿到数组里的每个元素,做相同或者相似的操作 ( 1 ) . forEach ----> 直接修改原数组
arr . forEach ( function (val , i , arr){
return 操作;
});
( 2 ) . map ----> 不修改原数组,返回操作后的新数组
var newArr = arr . map ( function (val , i , arr){
return 操作;
});
3. 过滤 和 汇总
( 1 ). 过滤 filter
var newArr = arr.filter( function (val , i , arr){
return 判断条件;
});
( 2 ). 汇总 reduce 数字就累加 , 字符串就拼接
var result = arr . reduce( function ( prev , val , i , arr ){
// prev --> 当前值 val 前面所有元素的和
return prev + val;
} , 基础值 );
ES6提供的箭头函数 ---> 为了简化一切匿名回调函数
1. 固定公式 :
( 1 ) . 去掉 function , ( ) 和 { } 之间加上 =>
( 2 ) . 如果形参只有一个 , ( ) 可以省略
( 3 ) . 若函数体只有一句话 , { } 可以省略
( 4 ) . 若函数体只有一句话且是return , { } 和 return 都可以省略
例子:
// 1. 筛选偶数
var newArr = arr.filter( function (val){
return val % 2 == 0 ;
});
var subArr = arr.filter( val => val%2 == 0);
//2. 汇总数组
var sum = arr.reduce((prev , val) => prev + val,1000);
//3.排序
arr.sort ( ( a,b )=> a - b);
字符串基础
一 . 字符串 :
- 定义 : 多个字符组成的只读字符数组 ( 但不是数组 );
- 只读 : 所有字符串API都不能修改原字符串 , 都会返回一个操作后新的字符串 ,只读不写
- 字符串 与 数组
-
相同点
(1) . 长度 : str . length
(2) . 下标访问 : str [ i ]
(3) . 可以遍历 : 和数组一样
(4) . 数组里的只读类型API , 字符串也可以使用 -
不同点
(1) 数组里修改原数组的API , 字符串也可以使用
-
二 . 引用/对象类型 (11种)
* String / Number / Boolean //--->包装类型
* Array / Function / Date / Math / RegExp(正则表达式) / Error
* Object (面对对象开发方式)
* Global (全局对象)
1. 包装类型 :专门用于将原始/基本/值类型的数据封装成一个引用类型对象的方法
( 1 ) 前辈发现字符串经常需要被操作 , 所以给我们提供了可以操作的属性/方法
( 2 ) 使用 :
只要试图在原始类型的变量上调用方法时 , 就会自动封装为引用类型 , 用完方法自动释放 变回原始类型;
2. 全局对象 : (Global/window)
( 1 ) Global 对象在浏览器中被 window 对象代替 , window对象中自然保存着页面中所有的全局变量/全局方法 , 在浏览器中window.xxx可以省略为 xxx;
( 1 ) 在其他编辑器中 , node.js中全局对象Global.xxx 不可以省略;
三 . 字符串 String --- API
1. 转义字符 : \
( 1 ) . 作用:将一些字符串中 和程序冲突的 字符 转换为原文 \符号
// 例如 : "我是"adan"" ==> "我是\"adan\""
( 2 ) . 包含特殊功能的符号
- \n : 换行
- \t : 大空格(TAB键)
- Unicode/ ASCII 编码字符 :写编码转换为对应的字符 \u4e00
| 编码 | ASCII | Unicode |
|---|---|---|
| 0 - 9 | 48 - 57 | 30 - 39 |
| A - Z | 65 - 90 | 41 - 5A |
| a - z | 97 - 122 | 61 - 7A |
| 汉字 | 19968 - 40896 | u4e00 - u9fa5 |
2. 大小写转换 :
( 1 ) . 转大写 :
var upper = str.toUpperCase( );
( 1 ) . 转小写 :
var lower = str.toLowerCase( );
3. 获取 指定下标 的字符
str.charAt( i ); ===> str[ i ];
4. 获取 指定下标 的字符 的ASCII码
var ascii = str.charCodeAt( i );
//ascii 码转为原文
var str = String.fromCharCode( ascii );
5. 检索 *****
- 检查索引 , 获取关键字第一个字符的下标
- var i = arr/str.indexOf( "关键字" , starti );
//检索从 starti 开始的右侧第一个字符开始查找 , 直到找到第一个
// starti 可以省略 , 默认从第一个字符串检索 , 直到找到第一个
// 通过返回值判断是否找到关键字:找到返回所在下标,未找到返回 -1
检索笔试题 :如何找到一个字符串中所有关键字的下标 ?
var str = "no zuo no die no can no bb"; // 找出所有no的下标
while ( (index = str.indexOf("no" , index+1)) != -1) { //index+1 表示从找到的下标的后一个字符开始查找
console.log("找到了,下标为" + index);
}
6. 拼接
var newStr = str.concat("新字符串", .....) ;
7. 截取 * : 3种
( 1 ). var subStr = arr/str . slice(starti , endi+1); //左开右闭,所以要+1
( 2 ). var subStr = str . subString(starti , endi+1); //同slice ,但不支持负参数
( 3 ). var subStr = str . subStr(starti , n); //n代表截取个数
8. 替换 ***
var newStr = str.replace("关键字/正则表达式" , "新内容");
// 结合正则表达式很牛 , 可以做一些自动识别,屏蔽词然后替换成*号
9. 切割/分割/分隔字符串 *****
var arr = str.split("自定义切割符");
// 将字符串从自定义的分隔符处断开,变成数组
// 切割符为空字符串的时候就是每一个字符都切开,相当于遍历装进数组
// 切割后,切割付消失
10. 去掉前后空白字符
var newStr = str.trim(); // trimStart( ) / trimEnd( )
// 可以用来做密码框内容识别
扩展 : JS创建HTML新元素 ---> 数据渲染页面
- 步骤 :
1. 创建新标签 : var elem = document.createElement("标签名");
2. 为新标签添加必要的属性和事件
3. 挂载上DOM树 / 渲染页面 : 父元素 . appendChild ( elem ) ;
四 . 数学 Math --- API
Math对象无需创建,有一些属性直接可以使用
1. 取整 : 3种
( 1 ). 上取整
// 超过就取下一个整数,小数位数不能超过15位
var num = Math.ceil(num);
( 2 ). 下取整
// 无论超过多少 ,都省略小数位数
var num = Math.floor(num);
( 3 ). 四舍五入取整
//只看小数第一位来舍入
var num = Math.round(num);
( 4 ). 扩展 : 四舍五入保留几位小数
num . toFixed(d);
//d是四舍五入保留d位小数,可以解决浏览器的舍入误差
取整笔试题
不使用toFixed方法 , 封装一个函数 , 用户穿如若数字和保留位数 , 实现四舍五入.
function toFixed(num,d){
num*=(10**d);
num=Math.round(num);
num/=(10**d);
return num;
}
var result=toFixed(Math.PI,2);
console.log(result);
2. 乘方 和 开方
( 1 ). 乘方 : Math . pow ( 底数 , 幂 ); ===> 底数 ** 幂
( 2 ). 开方 : Math . sqrt ( num );
3. 最大值 和 最小值
var max / min = Math.max / min (数据1,数据2,....);
4. 取绝对值
Math.abs(num);
5. 取随机数
// 网页中所有随机功能 , 底层一定是随机数
var num = Math.random( );
//在 0 - 1 之间取一个随机小数 , 搭配上parrseInt( ),只能取到0 , 不能取到 1 ,意味着取不到最大值
公式 :var num = parseInt ( Math.random( ) * ( max - min + 1 ) + min ) ;
五 . 日期 Date --- API
// 日期对象 : 提供了操作时间和日期的API , 所有日期API操作都是修改原日期 , 若要获得之前的日期 , 要先拷贝一个副本;
1. 创建 : 4种
( 1 ). 创建一个当前的日期
var now = new Date();
( 2 ). 创建一个自定义时间
var birth = new Date( "yyyy / mm / dd / hh : mm : ss" );
var birth = new Date( yyyy , mm , dd , hh , mm , ss" );//月份下标从 0 开始 , 0 是 1 月
( 3 ). 复制一个日期 --> 深拷贝
var end = new Date ( start );
( 4 ). 设置毫秒数
var date = new Date(毫秒数);
// 得出的时间 等于 1970年1月1日 8:00 (计算机元年) 的基础上 加上 毫秒数换算后的时间
2. 使用 :
( 1 ). 日期的本质就是保存了一个毫秒数 , --> 计时器
( 2 ). 两日期相减, , 得到一个毫秒差 , 可以换算出任意日期格式
3. API
( 1 ). 分量 : 时间的单位
- 年 月 日 星期 :FullYear / Month / Date / Day
- 时 分 秒 毫秒 :Hours / Minutes / Seconds / Milliseconds
- 其中每一个分量都有一对 get( ); set( ); ( 获取 / 设置 )方法 ,除了Day 没有set方法
( 2 ).分量的取值范围
| 分量 | 取值范围 |
|---|---|
| FullYear | 0 - 当前年份的数字 |
| Month | 0 - 11 |
| Date | 1 - 31 |
| Day | 0 - 6 (第一天是周日 , 0) |
| Hours | 0 - 23 |
| Minutes | 0 - 59 |
| Seconds | 0 - 59 |
| Milliseconds | - |
( 3 ). 对分量进行加减 : 先获取 ,再设置
date . setXXX ( date . getXXX( ) +/- n);
( 4 ). 格式化日期为本地字符串 :
date. toLocalString( );
// 有兼容问题 ...
定时器 *** 首次接触异步技术 , 是window的API
| 周期性定时器 | 一次性定时器 | |
|---|---|---|
| 开启 | timer = setInterval(callback , 间隔毫秒数 ) | timer = setTimeout(callback , 间隔毫秒数 ) |
| 停止 | clear.Interrval(timer); | clear.Timeout(timer); |
同步 / 异步
| 名称 | 特征 |
|---|---|
| 同步 | 代码逐行执行 , 前面的没有执行完 , 后面的不执行 |
| 异步 | 无论这块代码执行多长时间 , 都不会卡住后面的代码 |
BOM 基础
BOM定义 ---> Browser Object Model( 浏览器对象模型 )
专门用于操作浏览器的 , 使用不多 ,不如 ES 和 DOM 使用的多 , BOM没有标准 , 各个浏览器有自己的定义,除了老IE(8-);
1 . window对象
( 1 ) . 指全局对象 : 自然保存着全局变量和函数
( 2 ) . 指当前窗口本身 :
2. 属性:
-
获取浏览器的完整大小 :
window.outerWidth/outerHeight -
获取浏览器的文档显示区域大小 :
window.innerWidth/innerHeight -
扩展 : 获取屏幕的大小 : //不是window的属性
screen.Width/Height
3. API:
| 打开链接新方式 | open("url","target") | ||
|---|---|---|---|
| 当前页打开 , 可以后退 | open("url","_self"); | ||
| 当前页打开 , 不可以后退 | ** location.replace("新ul");** | ||
| 新页面打开 , 打开一个 | open("url","自定义name"); | ||
| 新页面打开 , 打开多个 | open("url","_blank"); |
| a标签扩展 | |
|---|---|
| 锚点 | 跳转到id |
| 下载按钮 | <a href="xx.exe/txt/rar/zip">下载</a> |
| 打开img / txt | <a href="xx.图片格式/txt">打开</a> |
| 直接书写js代码 | <a href="javascript : 代码">js操作</a> |
| 打开新窗口/新链接 方式 | newW = open("url" , "target" , "width=?,height=?,left=?,top=?") |
|---|---|
| 关闭窗口 | newW.close( ); |
| 改变窗口大小 | newW.resizeTo(width,height); |
| 改变窗口位置 | newW.moveTo(x轴,y轴); |
| 注意 | 要写第三个参数 ,要先设置定位 ,才能设置 Top,Left |
| window提供的弹窗 | |
|---|---|
| 警告窗 | alert("提示文字") |
| 输入窗 | prompt("提示文字"); //获取字符串 |
| 确认框 | var bool = confirm("提示文字"); //获取bool值 |
4. 事件:
| 名称 | |
|---|---|
| window.onload | 等待页面上所有资源加载完毕后才执行 |
| window.onresize | 窗口的大小发生变化就触发, 搭配 innerWidth 的判断相当于css媒体查询 |
| window.onscroll | 页面滚动监听 |
| window.scrollY | 获取滚动条当前位置 |
| window.offsetT / Left | 获取此元素当前距离浏览器顶部的距离 |
5. 本地 / 客户端存储技术:
( 1 ) cookie :
淘汰了,存储大小2kb,操作麻烦,要到处切割,最多保存30天
( 2 ) webStorage :
H5新特性 ,存储大小8mb,操作简单,永久保存在本地
(1) 分类
| 分类 | 特点 |
|---|---|
| sessionStorage | 会话级 ---- 浏览器关闭,数据清除 |
| localStorage | 本地级 ---- 只要不清除,永远保存在本地 |
(2) 操作:
| 操作 | 语法 |
|---|---|
| 添加 | xxxStorage.属性名="属性值"; |
| 读取 | xxxStorage.属性名; |
| 删除 | xxxStorage.removeItem("属性名"); |
| 清空 | xxxStorage.clear( ); |