学习JavaScript的第三周

98 阅读15分钟

转义字符:\

  • 何时使用:当字符串中出现了和程序相冲突的字符
    • 要在""中放入""
    • 具有特殊功能的转义字符
      • \n 换行
      • \t 制表符:就是tab键打出的一个空格
      • 也可以书写Unicode号来书写一个汉字 \uXXX
        • 汉字的第一个字: \u4e00
        • 汉字的最后一个字: \u9fa5

字符串的API

  • 英文转大小写
    • 大写:var upper = str.toUpperCase();
    • 小写: var lower = str.toLowerCase();
  • 获取字符串中的某个字符
    • str.CharAt(i);
  • 获取某个字符串中某个字符的ASCII码
    • str.charCodeAt(i);
    • 通过ASCII码转为原文
      • var x = String.fromCharCode(ascii);
  • 检索字符串
    • 何时使用:判断有没有,不重复

    • str.indexOf("关键字",starti);

    • 特殊:

      • starti可以省略,若省略默认是从0位置开始向右查找
      • 返回:若找到,返回的是关键字第一个字符的下标;没有找到就返回-1;
    • 数组也可以使用,其实在之前数组是没有这个方法的,在某次浏览器更新后,数组才可以使用(旧版本IE浏览器不能用)

    • 笔试题:找到所有关键字的下标

          var str="no zuo no die no can no bibi"; 
          var index=-1; 
          while((index=str.indexOf("no",index+1)h!=-1){ 
          console.log("找到了,下标为:"+index); 
          }     `
      
  • 拼接字符串
    • var newstr = str.concat(str1,str2,...)
  • 切割字符串
    • var str = str.split("自定义切割符")
    • 特殊
      • 切割符可以是自定义的,切割后会返回一个数组,数组元素中不包含是切割符
      • 若传入的切割符是"",字符串会被切散成一个个字符
  • 替换字符串
    • var newstr = str.replace("固定关键字"/RegExp,"新值")
  • 截取子字符串(3种) 【不改变原字符串】
    • var substr=str.slice(starti,end+1)
      • 不仅适用于字符串,数组也可以适用
    • var substr=str.substring(starti,end+1)
      • 只能适用于字符串,几乎和slice差不多,但不支持负数参数
    • var substr=str.substr(starti,n)
      • n代表截取的个数,不必考虑含头不含尾

JS创建页面元素并渲染DOM(3步)

失去焦点事件: .onblur
步骤:

  • 1、创建空标签
    • var 空标签 = document.creatElement("标签名");
  • 2、为此标签绑定必要的属性和事件
    • 空标签.属性名="属性值";
    • 空标签.on事件名=function(){操作;}
  • 3、让此标签上DOM数
    • 父元素.appendChild(子元素)

*****正则表达式

  • 什么是正则表达式;定义字符串中【字符出现规则】的表达式
  • 何时使用:切割 替换 验证
  • 如何使用
    • 1、最简单的正则:关键字原文 如匹配no /no/ig
      • i:忽略大小写
      • g:全部匹配
    • 2、备选字符集:一个备选字符集--规定一位字符可能出现的情况
      • 如何使用:只要关键字有多种情况时
      • 如何使用:/[备选字符集]/
        • 强调:
          • 一个[]只能管一个字
          • 问题:正则默认只要满足后,就不再管后续操作
        • 特殊:
          • 如果备选字符集中有部分是连续的,则可以用“-”省略掉中间部分
          • 除了XXX之外,都可以===/[^XXX]/ 范围太广,不推荐使用
    • 3、预定义字符集 一些常用的字符集
      • 一个数字:\d
      • 一位数字、字母、下划线:\w
      • 一位空白字符:\s ====空格、制表符、换行
      • 除了换行以外的任意字符:“.”====范围太广,不推荐
      • 问题:预定义字符集是固定的,不灵活
      • 建议:开发时优先使用预定义字符集,预定义字符集满足不了,再使用备选字符集补充
    • 强调:不管是备选字符还是预定义字符集都只管一位
    • 4、量词
      • 如何使用:
        • 1、有明确数量
          • 字符集{n,m}:前边相邻的字符集最少出现n次,最多出现m次
          • 字符集{n,}:前边相邻的字符集最少出现n次,多了不限
          • 字符集{n}:前边相邻的字符集只出现n次
        • 2、没有明确数量
          • +:前边相邻的字符集,至少出现一次,多列不限
          • *:前边相邻的字符集,可有可无,多了不限
          • ?:前边相邻的字符集,可有可无,最多出现一次
    • 5、指定匹配位置
      • ^以XXX开始
      • $以XXX结束
      • 特殊:若同时使用了,前加^后加$,表示从头到尾完全匹配,做验证时必须这么写
    • 6、选择和分组
      • 选择:可以再多个条件中选择一个
        • 规则1|规则2
      • 分组:选择和分组搭配着用
        • (规则1|规则2)
    • 7、预判:目的--密码强度 ======输入4-6位密码,可以输入字母和数字,但必须要有一位大写和一位数字的组合
      • /^(?![0-9]+))/ =====不能全由数字组成,可能有大写字母、小写字母、汉字、特殊符号、
      • /^(?![A-Za-z]+))/=====不能全由大写组成,也不能全由小写组成,也不能由大写和小写的组合组成,可能有数字、汉字、特殊符号、日文、韩文.....

字符串支持正则的API

  • 切割:str.split("自定义切割符号")
    • 自定义切割符可以用正则来表示
  • ******替换
    • 1、基础替换法

      • str.replace(/正则表达式/gi,"新内容");
      • 注意:替换时,不要前加^后加$,我们只需要找到关键字做替换而已,若要找到全部的就需要加上后缀g
      • 问题:替换的新东西,只能时一个固定的
    • 2、高级替换法

          //此回调函数会自动调用,找到几个关键字就会执行几次
          str=str.replace(/[我卧握窝][去槽操曹草]+/g,function(key,i.str){
          console.log(key);//当前次正则匹配到的关键字
          console.log(i);//当前次正则匹配到的关键字的下标console.log(str);//原文本身
          returnkey.length==2?"**":"***";
          })
          
      
    • 3、格式化:若替换时,正则中带有分组,回调函数会得到更多的形参

        var str="500103198602215933";
        var reg=Ad{6](1d{4))(Id{2))(d{2))\d{4)/;
        str=str.replace(reg,function(key,a,b,c,i,str){
              console.log(key);
             //IF则匹配到的内容console.log(a);
             //第一个分组匹配到的内容console.log(b);
             //第二个分组匹配到的内容console.log(c);
             //第三个分组匹配到的内容
             //你有多少个分组就会多出多少个形参,但是最后两个—定是下标和原文
             console.log(i);
             console.log(str);
             return a+"年"+b+"月"+c+"日";})
         console.log(str);
      

正则对象

  • 创建
    • 直接量方式: var reg = /正则表达式/后缀
    • 构造函数方式:var reg = new RegExp("正则表达式","后缀")
  • 方法 验证 var bool = reg.test("用户输入的东西")
    • true 表示用户输对了,false表示用户输错了

Math

  • 强调:不能、不需要创建,浏览器自带的
  • 属性:Math.PI
  • API
    • 1、取整
      • 上取整:只要超过,就会取下一个整数

        • Math.ceil(num); 小数位数不能超过15位,超过后会失效
      • 下取整 无论超过多少,都省略小数部分

        • Math.floor(num);
      • 四舍五入取整

        • Math.round()
      • 以上三个只能取整,不能保留小数位数 === num.toFixed(d)

      • 笔试题:封装一个自定义函数,按照小数位数四舍五入,返回数字类型

        function fun(num,d){
             num*=Math.pow(10,d);
             num=Math.round(num);
             num/=Math.pow(10,d);
             return num;
        }
        
    • 2、开方和乘方
      • 开方:Math.sqrt(num);
      • 乘方:Math.pow(底数,幂)
    • 3、最大值和最小值
      • var max/min=Math.max/min(num1,num2,num3,...);
      • 可以获取传入输入参数中的最大或最小值
      • 问题:不支持传入数组参数,比较数组的最大值和最小值
      • 解决:Math.max/min.apply(Math,arr);
        • 其实apply可以打散数组,将每个元素单独传入
        • 笔试题:比较出数值中最大值或最小值(2个方法)
    • 4、绝对值
      • Math.abs(num)
    • 5、随机数
      • Math.random() ===在0-1之间取随机的小数,可能取到0,但不可能取到1
      • 在min~max之间取随机整数
        • parseInt(Math.random()*(max-min+1)+min);
        • 页面上一切带有随机功能的,底层一定用到了随机数

Date

  • 何时使用:只要计算事件,就必须用到Date对象
  • 如何使用
    • 1、创建(4种)
      • 1)、创建一个日期对象,获取客户端当前时间
        • var now = new Date();
      • 2)、创建一个自定义时间
        • var date = new Date("yyy/MMM/dd hh:mm:ss");
      • 3)、创建一个自定义时间
        • var date = new Date(yyy,MM-1,dd,hh,mm,ss);
        • 取值范围:MM:0~11月份,使用时需要修正
      • 4)、复制一个日期对象
        • 为什么:日期对象的API都是直接修改原日期对象的,无法获得修改之前的日期
        • 何时使用:希望同时获得修改前和修改后的两个日期,则应该先复制一份,然后对其中一份进行修改
        • var end = new Date(start);
    • 2、使用
      • 1)、两个日期对象可以相减,得到一个毫秒差,通过毫秒差换算出任何想要的一部分
      • 2)、API操作
        • 年月日星期: FullYear Month Date Day
        • 时分秒毫秒:Hours Minutes Seconds Milliseconds
          • 每一个分量都有一对getXXX和setXXX方法
            • 特殊:Day没有set方法
          • 取值范围:
            • FullYear:当前年份的数字
            • Month:0~11 计算机中的月份比现实中少1
            • Date:1~31
            • Day :0~6 0代表星期天
            • Hours:0~23
            • Minutes/Seconds :0~29
        • 日期对象会自动进制
        • 建议:对一个日期的某个分量做计算
          • date.setXXX(date.getXXX()+/-n);
          • 10分钟后:date.setMinutes()(date.getMinutes()+10);
      • 3)、日期格式化:
        • date.toLocalString(): //会转为一个本地日期格式的字符串
        • 此方法有兼容性问题,旧版本IE浏览器和主流浏览器输出的内容不一样
        • 解决:自定义format函数

Error对象:错误对象

  • 览器自带的4中错误留下 ====帮助快速找到错误
    • SyntaxError ===语法错误或书写错误
    • ReferenceError ===引用错误:没有创建就使用
    • TypeError ===类型错误:使用了不是自己的属性和方法
    • RangeError ===范围错误:只有一个API会遇到,num.toFixed(d) d的取值在0~100之间
  • 错误处理:当程序发生错误时,保证程序不会异常终端
    • 为什么:程序默认只要碰到错误就会停止或者闪退,用户体验感差

    • 如何处理

          try{
          可能发生错误的代码
          }catch(err){
          发生错误才会执行,err形参会自动得到错误的信息
          }
      
    • 放在try里面的代码,性能都会被降到最低

    • 解决:完全可以用if..else代替try..catch,所哟有的一切都可以提前预判

      • 任何客户端都是坏人,都需要防一下
        • if..else..
        • !isNaN
        • 正则验证
  • 抛出自定义错误
    • throw new Error("自定义错误");

*****Function对象

  • JS中的函数也是一个对象,函数名其实也是引用函数对象的变量
  • 考点
    • 1、创建;3种
      • 1、声明方式 ----完全声明提前
      • 2、直接量方式
      • 3、构造函数方式
        • var 函数名 = new Function("形参",..."函数体:return 返回值;")
        • 何时使用:若函数体不是固定的,而是字符串动态拼接
    • 2、***作用域
    • 3、***声明提前
    • 4、***按值传递
    • 5、***重载(overload):相同函数名,更具传入的是处男不同,会自动选择对应的函数指向
      • 为什么:减轻程序员的负担
      • 问题:JS的语法不支持重载,若有相同的,后面的会覆盖前面的所有
      • 解决:在函数内部有一个对象===arguments
        • 什么是arguments对象:函数中,自带的,不需要创建的,是一个类数组对象,作用:接收所有的实参
          • 只有3个点是和数组相同的
            • 都可以使用下标访问某个元素 arguments[]
            • 都可以使用length获取长度 arguments.length
            • 都可以遍历拿到每一个元素==for循环
            • 强调:类数组对象不是数组,所有的数组API,类数组都不能用
          • 何时使用:
            • 不需要形参,也可以接收所有的实参
            • 变相实现重载,在函数内部判断传入的参数的不同,执行不同的分支操作
    • 6、***匿名函数
      • 为什么:节约内存,匿名函数没有变量引用着,用户就会自动释放
      • 1)、匿名函数自调:只会执行一次,执行完毕就会自动释放,代替全局写法,节约内存空间
        • (function(){console.log("我是匿名自调");})();
      • 2)、*匿名函数回调:在函数调用时,传入的实参又是一个匿名函数,不需要程序员调用,会有函数自动执行
        • 回调函数--匿名函数,只要不是自调就是回调
          • arr.sort(function(a,b){return a-b;})
          • str.replace(reg,function());
        • 搭配上ES6的箭头函数,简化了一切的回调函数

Function的最后一个考点*****

  • 1、作用域
    • 全局作用域
      • 容易被污染
    • 函数作用域
      • 用一次就释放了,不能反复使用
  • 2、函数的执行原理===5步
    • 程序加载时
      • 创建执行环境(ECS):保存函数调用顺序的数组
      • 首先压入全局执行函数(全局EC)
      • 全局EC中引用着全局对象window
      • window中保存着全局变量
    • 定义时
      • 创建函数对象:封装代码段
      • 在函数对象中定义了scope数组,记录着函数来自的作用域
      • 全局函数的scope都是window
    • 调用前
      • 在执行环境栈(ESC)中压入新的函数的EC
      • 创建出活动对象(AO):保存本次函数调用用到的局部变量
      • 在EC中添加scope chain(作用域链)属性引用着AO
      • 设置AO的parent属性为函数的scope引用的对象
    • 调用时
      • 变量的使用规则:优先使用局部变量,局部没有找全局,全局没有就报错
    • 调用完
      • 函数的EC回出栈,AO自动释放,局部变量也就自动释放
    • 两链一包
      • 作用域链(scope chain):以函数的EC中的scope chain属性为起点,经过AO,逐级引用,形成一条链式结构
      • 作用:查找,带来了变量的使用规则

闭包 保护一个可以【反复使用的局部变量】的一种此方法结构*****

  • 为什么:全局变量有缺点,局部变量也有缺点
  • 如何使用:
    • 1)、两个函数进行嵌套

    • 2)、外层函数创建受保护的局部变量,并且返回内存函数

    • 3)、内层函数在操作受保护的局部变量

    • 例子:

           function factory(){
               var i = 0;
               return function(){
                   i++;
                   return i;
               }
            }
            var icbc=factory();
            var abc=factory();
            console.log(icbc());
            console.log(icbc());
            console.log(abc());
            console.log(abc());
            console.log(icbc());
      
  • 强调:
    • 1、判断闭包:有没有两个函数嵌套,并且外层啊哈四年胡创建了变量,return了内层函数
    • 2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有几个副本
    • 3、同一次外层函数调用,返回的内层函数,都是使用的同一个受保护的变量
  • 缺点:唯一的缺点:受保护的变量永远不会被释放,过渡使用闭包,会导致内存泄漏
  • 使用场景:防抖节流,减少DOM树的修改,提升性能--3个时间回非常影响性能
    • 1、elem.onmousemove --鼠标移动就会触发,触发次数很多很快

    • 2、window.onresize===窗口的尺寸发生变化就会触发

    • 3、input.oninput ===input 输入框的内容发生变法就会触发

    • 防抖节流公式:

             var timer; //是受保护的变量
             return function () { //操作受保护的变量 
                 if (timer){ 
                     clearTimeout(timer);
                 }
                 timer = setTimeout(function () {
                 考虑要做的操作是什么 
                 } 
                 }, 1000)}
      

Object:面向对象开发方式*****

  • 三大特点:封装、继承、多态
  • 面试题:面向过程和面向对象开发方式的区别?
    • 面向过程:开始、经过、结束这个过程,
    • 面向对象:对象(属性和方法),如果这个世界有各种属性和各种方法,但是连一个对象/生物都没有,那这些东西就没有具体的意义
  • 学习如何创建自定义对象
    • 1、封装/定义/创建对象:3种
      • 1)、直接量方式
        • var obj = {"属性":属性值,...."方法名":function(形参){函数体}}
        • 强调:
          • 1、属性名和方法名的引号其实是可以省略的,但是不建议,因为以后我们会学习一种数据格式叫做JSON,要求属性名和方法名的【双引号】不能省略
          • 2、如何访问对象的属性和方法
            • 对象名.属性名 === 对象名["属性名"]
            • 对象名.方法名() === 对象名"方法名";
            • 特殊:
              • 访问到不存在的属性,返回undefined
              • 随时随地可以添加不存在的属性和方法
          • 3、希望获得对象中的所有东西:遍历对象====for in 循环
          • 4、若希望在对象的方法内部使用对象自己的属性,就需要用this.属性名
            • this指向
              • 1、单个元素绑定事件时,this指的是这个元素
              • 2、多个元素绑定事件时,this指的是当前元素
              • 3、函数中,this指的是谁在调用这个函数this就指向谁
              • 4、定时器中,this指的是window
              • 5、箭头函数,this指的是外部对象
              • 6、自定义构造函数中,this指的是当前正在创建的对象
      • 2)、构造函数方式:
        • var obj = new Object(); //空对象
        • obj.属性名=属性值;
        • obj.方法名=function();
      • 以上两种创建方式有一个缺点:仅仅适合创建单个对象,如果创建多个对象,代码荣誉的太高
      • 3)、专门为创建多个对象准备的
        • 自定义构造函数:2步
          • 1、创建构造函数
          • 2、调用自定义构造函数创建出对象
      • 面向对象开发方式的好处:
        • 不适合初学者使用,逼格高

        • 特地把每一块功能分开

        • 铁索连舟-更符合现实生活

        • 所有东西都包含在一个对象之中-更符合现实生活