JavaScript学习 --- 第二周

133 阅读14分钟

数组的基础

一. 数组创建方法上的区别 ( 填坑 )

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("自定义连接符");

  1. 语法 :
    var str = arr . join ("自定义连接符") ;

  2. 固定套路 :
    ( 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,...);

  1. 语法 :
    var newArr = arr.concat(新值1,数组2,...新值n);
  2. 注意 :
    concat 可以传入数组参数,但会打散后再拼接 , 要直接写作[ ]形式;

3. 截取子数组 ---> arr.slice(starti,endi);

slice ---> 片

  1. 语法 :
    var subArr = arr.slice(starti,endi);

  2. 注意 :
    (1) endi可以省略 , 默认从starti截取到数组结束
    (2) endi和starti都省略 , 默认从头到尾复制一份完整的副本给subArr ; ---> 深拷贝
    (3) 支持传入负参数,代表倒数第几个 ; ---> -1就是倒数第一个

------以上API不改变原数组返回修改后的新值 , 以下API会改变原数组------

4. 删除 / 插入 / 替换 ---> arr.splice();

splice ---> 拼接

  1. 删除:
    var dels = arr.splice(starti,n);
    //n -->删除个数 , dels 接住的是被删除的元素组成的数组 , 没删除东西也会返回一个空数组

  2. 插入:
    arr . splice (starti , 0 , 值1,值2.....);
    //n=0 , 删除0个 , 但在starti后面插入新的数组元素
    //splice插入数组元素不会打散,会导致数组里有些一维数组

  3. 替换:
    var dels=arr.splice(starti,n,值1,值2,....值n);//删除的个数和插入的个数不必一致

5. 翻转数组 ---> arr.reverse();

6. 数组排序 ---> arr.sort();

  1. 语法 :
    arr.sort();
    //默认将arr中的元素逐一转为字符串 , 按照ASCII码/Unicode码来按位pk
    //出现这样的情况 : [22, 333, 36, 37, 456, 65, 98]

  2. 数字按升序排列

       arr.sort ( function ( a,b ) {   //     a --> 前一位数字     b --> 后一位数字
       return a-b;  // a-b > 0 ab前后交换
                            //a-b <= 0  ab位置不变
       });
       //匿名回调函数 , sort方法内部已调用
    
  3. 数字按降序排列

       arr.sort ( function ( a,b ) {   //     a --> 前一位数字     b --> 后一位数字
       return b-a;  
       });
    

7. 栈和队列 (本质是数组 , 提供了删除/插入的方法)

  1. : 先进后出 ,一端封闭 , 一端进出 ;
  2. 队列: 先进先出, 一端进 , 另一端出 ;
  3. 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);

字符串基础

一 . 字符串 :

  1. 定义 : 多个字符组成的只读字符数组 ( 但不是数组 );
    • 只读 : 所有字符串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
编码ASCIIUnicode
0 - 948 - 5730 - 39
A - Z65 - 9041 - 5A
a - z97 - 12261 - 7A
汉字19968 - 40896u4e00 - 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 ).分量的取值范围

分量取值范围
FullYear0 - 当前年份的数字
Month0 - 11
Date1 - 31
Day0 - 6 (第一天是周日 , 0)
Hours0 - 23
Minutes0 - 59
Seconds0 - 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. 属性:

  1. 获取浏览器的完整大小 :
    window.outerWidth/outerHeight

  2. 获取浏览器的文档显示区域大小 :
    window.innerWidth/innerHeight

  3. 扩展 : 获取屏幕的大小 : //不是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( );