JavaScript第三周笔记

本文详细介绍了JavaScript中的字符串API,包括检索字符串、正则表达式及其使用,如字符检索、量词规定、预定义字符集等。此外,还讲解了正则表达式的应用,如替换、切割字符串,以及正则对象的使用。同时,概述了Math和Date对象,以及Error对象在错误处理中的角色。文章最后提到了Function对象、闭包和面向对象开发的相关概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

start i  代表开始位置

end    i   代表结束位置

字符串API

英文转大小写

toUpprecase   转大写

toLowerCase  转小写

获取字符串的某一个字符

str.codeAt();

获取字符串字符的ASCII码

str.charCodeAt();

通过ASCII码值转回原文

str.fromcharCodeAt();

补充:CSS    ::section{background:transparent;}   页面双击文字会出现蓝色背景的选择效果,该代码把双击选择效果设置成了透明色

检索字符串:检查索引/下标

使用:判断有没有该关键字,不重复

var i = str.indexOf("关键字",strat i);

特殊:

1.start i可以省略,如果省略默认从0位置开始向右查找

2.返回:如果找到了,返回关键字的第一个字符的下标

★★★没找到返回-1,重点:我们不关系下标为多少,只关心下标是不是-1,为-1就是说明没有,如果不为-1,说明存在

3.数组也可以使用:其实以前的数组没有这个方法,某浏览器更新后,数组才可以使用(老IE浏览器(ie8以下的)用不到)

补充:笔试题:

var str="no zuo no dai no can no bb";
var index=-1;
while((index=str.indexOf("no",index+1))!=-1){
    console.log("下标为"+index);
}

拼接字符串

var newStr=str.concat(str1,str2.....);还不如 + 连接字符串

截取字符串:三种方式

arr.slice(strat i,end i+1);   开始位置包含,结束位置不包含(含头不含尾)

arr.subString(strat i,end i+1);    几乎和slice用法相同,但是不支持负数  

arr.substr(strat i, n);    从开始位置,截取N个数,开始位置和结束的位置都包含 (含头含尾)

这里推荐使用  arr.substr(strat i, n);

替换字符串

str.replace("固定关键字","新内容");

此方法搭配正则就很好

切割/分隔字符串 

var arr=str.split("自定义切割符");

特殊:

1.切割符可以自定义,切割后返回的是一个数组,数组中不在包含切割符

2.如果传入的切割符是一个“” 空,每一个字符都会被切

扩展:JS创建页面元素并且渲染上DOM树:3步

1、创建空标签: var 新元素=document.createElement("标签名");

2、为此标签设置必要的属性和事件
      新元素.属性名="属性值";
      新元素.on事件名=function(){操作}

3、把新元素上DOM树
      父元素.appendChild(新元素);

正则表达式

正则表达式:定义字符串中出现规则的表达式

使用:做切割/替换/“验证”的时候使用

最简单的正则就是关键字原文,写法和以前的字符串不同 例:“no” --> /no/gi

i:忽略大小写

g:替换所有;替换默认替换第一个匹配的字符

var  a = "a b c a d e f a g a";
a.replace(/no/gi,"p");

被选字符集:规定一位字符可能出现的情况

强调:一个中括号只能管理一个值

问题:正则只要满足后,就不在关后续操作,后续用户可以乱输入

解决:做验证,希望用户根据我们的想法来操作;必须写成:/^备选字符集$/ /^表示从开头 /$表示到结尾 表示用户从头到尾都必须完全匹配

特殊

如果被选字符集unicode号是连续的,就用-省略中间部分

比如: 一个数字[0-9]

一个字母[A-Za-z]

一个数字,字母,下划线[0-9A-Za-z]

一个汉字[\u4e00-\u9fa5]

预定义字符集:

一个数字:\d

一个英文,数字,下划线:\w

一个空白字符: \s

一位除了换行外的所有字符: . (点) 不推荐此字符集

问题:预定义字符集,是固定的,不够灵活

开发时,优先使用预定义字符集,在预定义字符集满足不了时,就使用备选字符集补充

强调:备选字符集和预定义字符集都只能管一位字符

量词规定一个字符集出现的次数

使用:

有明确数量:

字符集{n,m}; 前边相邻的字符集最少出现n次,最多出现m次

字符集{n}; 前边相邻的字符集最少出现n次,不限制最多出现次数

字符集{n}: 前边相邻字符集必须出现n次

没有明确数量:

字符集? 该字符集可有可无,最多一次

字符集* 该字符集可有可无,不限制最多出现次数

字符集+ 至少写一个该字符集,不限制最多出现次数

指定匹配位置

^:以...开头

$:以...结尾

特殊:如果同时使用了 前面^和后面$({/^ $/ } 从头到尾完全匹配

选择和分组

选择:可以在多个条件中,选择一个

规则1|规则2(字符集1|字符集2)

分组:选择和分组一般情况下是搭配使用------添加子规则

(规则1|规则2)

新老身份证的正则

/^(\d{15}|\(d{17}[0-9Xx])&/

预判

目的:密码强度:4-6位密码,可以输入字母数字,但必须有一位大写和以为数字组成

公示:固定搭配

/^(?![0-9]+$)$/    不能全由数字组成,可能有大写字母,小写字母,汉字,特殊符号,其他语言....


/^(?![0-9]+$)[0-9A-Za-z]{4}$/  不能全数字,只能输入四位,可以是小写字母大写字母数字之间的组合  

^(?![A-Za-z]+$)$/   不能全有英文组成,可能有数字,可能有汉字,可能有特殊符号,其他语言.... 

/^(?![A-Za-z]+$)(?![0-9a-z]+$)(?![0-9A-Z]+$)[0-9A-Za-z]{4,6}$/    只能输入由一个大写字母和一个小写字母和一个数字组成的4-6位密码

/^(?![A-Za-z]+$)(?![0-9a-z]+$)[0-9A-Z]{4,6}$/  只能输入一个数字和大写字母组成的4-6位密码

字符串支持正则的API

切割

var a = string.split("固定切割符")

替换

var a = string.replace(“关键字”,"新值")

格式化

如果替换式,正则中,带有分组,那么你的回调函数会由更多的形参

var str="500103198602215933";
            var reg=/\d{6}(\d{4})(\d{2})(\d{2})\d{4}/;
            str=str.replace(reg,function(key,a,b,c,i,str){
//                console.log(key);//正则匹配到的内容
//                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=rew RegExp("正则表达式","后缀")

     验证方法: var bool=reg test("用户输入的东西");

     true 用户输对了 flase 用户不通过

     失去焦点事件onblur

     获得焦点事件onfocus

     提交事件onsubmit

     阻止表单提交form.οnsubmit=function(){}

Math:专门用于提供数学计算的API

强调:不需要创建,浏览器自带的

属性:Math.PI

API:

向上取整:Math.ceil()

向下取整:Math.floor()

四舍五入:Math.round()

固定精度:Math.toFixed() 缺点:返回的是字符串 用parseFloat包起来

固定长度:Math.toPrecision()

取整:Math.parseInt()、位运算

乘方/开方

乘方:Math.pow(底数,幂)

开方:Marh.sqrt()

最小值,最大值

Math.max()

Math.min()

缺陷:不支持传入数组参数,不能比较数组的最大值和最小值

解决:Math.max/min.apply(Math,arr);

apply可以悄悄打散数组,将每一个元素单独传入--ES5带来的特性

apply可以借用方法

笔试题:比较出数组中的最大值和最小值(2 种方法) for循环遍历比较,Math.max.apply(Math,arr)

绝对值,随机数

绝对值Math.abs();

随机数Math.random(); 默认0-1之间取随机数,可以取到0,但不可能取到1

parseInt(Math.randow()*(max-min+1)+min);随机整数

在min和max之间取随机数

parseInt(Math.random()*(101)); 可以取到的最大值100,最小值0

parseInt(Math.random()*(100)+1); 可以取到的最小值1以及最大值100

笔试题:

封装自定义函数,按照任意小数位四舍五入,返回数字类型

function dy(num,d){
		num*=Math.pow(10,d);
		num=Math.round(num);
		num/=Math.pow(10,d);
		return num;
}
var res=dy(Math.PI,3);
console.log(res);

Date:封装了一个时间对象提供了对时间进行操作的API的对象

使用:计算和时间相关的,就得用到date对象

创建(4种):

**1.创建一个日期对象,获得客户端的当前时间
var a = new Date();
**2.创建一个自定义时间:
var time = new Date("1986/02/26 12:32:54");
3.创建一个自定义时间:
var time = new Date(yyyy,MM,dd,hh,mm,ss)
取值范围:MM  0~11月   月份需要修正 0=1月 1=2月...11=12月
**4.复制一个日期对象
日期对象的API都是直接修改日期对象的原值,无法获取修改之前的日期
解决:如果希望同时获取修改前和修改后的日期,则应该先把原日期复制一份,再去修改其中的一份日期
var start = new Date("1986/02/26 12:32:54");
var copy = new Date(start);

使用:

1.拿着两个日期对象可以相减,得到一个毫秒差,通过毫秒差换算出你想要的任何一部分

2.日期的API操作:分量:时间单位

年/月/日/星期:Fullyear / Month / Date / day

时/分/秒/毫秒:Hours / Minutes / Seconds / Milliseconds

1.获取方法:
getFullyear / getMonth / getDate 
getHours / getMinutes / getSeconds / getMilliseconds
设置方法:
setFullyear / setMonth / setDate 
setHours / setMinutes / setSeconds / setMilliseconds

特殊:Day(星期):没有set方法 

2.取值范围:
  Fullyear:就是当前年份的数字
  Month:0~11,计算机中的月份比现实-1
  date:1~31
  day:0~6  0代表星期天
  Hours:0~23 
  Minutes,Seconds:0~59
  
3.日期对象和字符串能用的API不同,而且日期对象可以自动进制
  建议:对一个日期的某个分量做计算
      date.setXXXX(date.getXXX() +/- N);
  例如:
      date.setMinutes(date.getMinutes() + 10); 加十分钟
      
4.日期格式化
date.toLocaleString();(不推荐) 会转为一个本地日期格式的字符串,不能自动进制,也不能用日期的API,但是可以使用字符串的API   
  缺点:具有兼容性问题
  解决:自定义函数format

Error对象(查询错误)

SyntaxError——语法错误:符号或者语法错了

ReferenceError——引用错误:使用没有创建过的东西

*typeError——类型错误:使用了一个不属于自己的属性或者方法

RangeError——范围错误:只有一个API会遇到,Math.PI.toFiexd(d); d的范围必须在0-100之间

2.错误处理

当程序发生错误时,保证程序不会异常中断的机制

程序默认遇见错误就会停止后续代码的执行,用户体验差

处理:

try{
    console.log(Math.PI.toFiexd(-1)); //取值范围错误 
}catch(err){
    console.log(err);  //输出错误信息,建议自己加上中文错误描述
    alert("XXXXXXX")
}

可以用if...else....代替try....catch....

if....else....错误提示可以用:

1. throw new Error("XXX");

2. console.log("XXX")

点击获取页面X轴坐标 xxx.clientX;

Function对象

JS中函数就是对象,函数名其实就是引用函数对象的变量

1.创建:三种

声明方式:function 函数名(形参1,形参2....){函数体;return 返回值;} 完整的声明提前

直接量方式: var 函数名=function(){函数体;return 返回值;}声明提前

构造函数方式:var 函数名=new Function("形参1","....","函数体;return 返回值;"); 无论参数什么类型,创建函数的时候都必须用双引号包起来(函数体不是固定的,而是字符串动态拼接的时候使用)

2.★★★重载(overload)

相同函数名,根据传入的实参不同,会自动选择对应的函数执行

问题:JS的语法不支持重载!JS不允许同时存在多个同名函数,如果同时存在,那最后一个函数值会覆盖前面的函数值

解决:函数内部对象:arguments

arguments函数内部自带的,不需要创建,类数组对象,作用:接受所有的实参

类数组对象(类似数组):

可以用下标访问某个元素;可以用length获取长度;可以遍历拿到元素,但不等于数组,不支持数组所有的AIP

何时使用:1.以后不需要形参,也接住所有的实参

2.变相实现重载:

3.★★★匿名函数

创建的函数,没有函数名引用

何时使用:如果函数只会执行一次的时候使用; 为了节约内存,匿名函数没有变量引用,用完就自动释放

如何使用

1.匿名函数自调:

(function(){函数体;}) ( )

★2.匿名函数回调:函数调用时,调入的实参,又是一个匿名函数,不需要我们去调用,主函数会自动执行

arr.sort(function(a,b){return a-b;})
str.replace(reg.function(){})

匿名函数只要不是自调,就是回调:

以后搭配上ES6的箭头函数:简化了一切回调函数

闭包(重要)

1.作用域(scope)

全局作用域

随处都可以用,可以反复使用,但是很容易被污染(被改变)

函数作用域

不会被污染,但是只有函数调用时内部可用,调用结束后会释放,不可以反复使用,每一次使用都是重新开始

函数的执行原理

一.程序加载时

创建执行环境栈(ECS):保存函数调用顺序的数组

首先压入全局执行环境(全局EC)

全局EC中引用着全局对象window

window中保存着全局变量

二.定义时

创建函数对象:封装函数段

在函数对象中定义scope属性,记录着函数来自的作用域

全局函数的scope都是window

三.调用前

在执行环境ECS压入新的函数EC

创建出活动对象(AO):保存本次函数调用用到的局部变量

在EC中添加一个scope chain (作用域链)属性引用着AO

设置AO的parent属性为函数的scope引用的对象

四.调用时

变量的使用规则:有些使用局部变量,没有局部变量就找全局变量,没有全局变量,就会报错

五.调用完

函数的EC会出栈,AO自动释放,局部变量也会自动释放

★★★★★包:保护一个可以[反复使用的局部变量]的一种此法结构
为什么:全局变量:缺:容易被污染
局部变量:缺: 一次性
如何使用:
1、两个函数进行嵌套
2、外层函数创建受保护的局部变量,并且返回内层函数
3、内层函数在操作受保护的局部变量
强调:
1、判断闭包,有没有两个函数在嵌套,并且外层函数创建了变量,return 了内层函数
2、外层函数调用几次,就创建了几个闭包,受保护的变量就有了几个副本
3、同-次外层函数调用,返回的内层函数,都哦是使用同一个受保护的变量
缺点:唯-的缺点:受保护的变量永远不会被释放,过度使用闭包,会导致内存泄漏
使用场景:防抖节流:减少DOM树的修改,提升性能- 3个事件会非常的影响性能,性能差、
1、elem.onmousemove   鼠标移动就会触发,触发次数很多很快,但是不要让他疯狂的渲染DOM
2、window.onresize   窗口的尺寸积要发生变化就会触发,触发次数很多很快,但是不要让他疯狂的渲染DOM
3.input.oninput   input框输入的内容发生变化,就会触发

防抖节流
window.οnresize=function(){
    return inner();
}
function fdjl(){
    var timer;
        return function(){
         if(timer){clearTimerout(timer)}
         timer=setTimeout(function(){
              函数体;(需要做的操作)
         })
        }
}
var inner=fdjl();//inner()内层函数才是写在事件中的操作

Object面向对象开发方式

三大特点:封装,继承,多态

面试题:简单说一下你了解的面向过程和面向对象 开发方式的区别?

面向过程:开始--经过--结束,从一开始学习到学习写法都是面向过程

面向对象:对象(属性和方法),如果这个世界有各种属性和各种方法,但是练一个对象/生物都没有,那些对象就没有具体意义

创建自定义对象:

1.直接量方式:

var obj={ 
            "属性名1":属性值1,    
            "属性名2":属性值2, .....
             "方法名":function(形参1...){函数体}; 
}

例子:轮播的对象封装

HTML部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
</head>

<body>
    <div id="lunbo" class="banner">
        <img class="active" src="./images/banner.jpg" alt="">
        <img src="./images/banner02.jpg" alt="">
        <img src="./images/banner03.jpg" alt="">
        <img src="./images/banner04.jpg" alt="">
        <button><</button>
        <button>></button>
        <ul>
            <li xb="0" class="active"></li>
            <li xb="1"></li>
            <li xb="2"></li>
            <li xb="3"></li>
        </ul>
    </div>

</body>

</html>

CSS部分


        * {
            margin: 0;
            padding: 0;
        }

        div {
            width: 100%;
            height: 500px;
            position: relative;
        }

        div>img {
            width: 100%;
            height: 100%;
            position: absolute;
            opacity: 0;
            transition: 1s;
        }

        div>img.active {
            opacity: 1;
        }

        div>button {
            width: 50px;
            height: 50px;
            position: absolute;
            top: 50%;
            margin-top: -25px;
            border-radius: 50%;
            border: 1px solid red;
            cursor: pointer;
        }
        div>button:hover{
            background: rgba(0, 0, 0, 0.3);
        }
        div>button:active{
            background: rgba(0, 0, 0, 0.7);
        }
        div>button:nth-of-type(1) {
            left: 0;
        }

        div>button:nth-of-type(2) {
            right: 0;
        }
        ul{
            position: absolute;
            z-index: 2;
            top: 90%;
            left: 50%;
            margin-left: 10px;
        }
        ul>li{
            width: 20px;
            height: 20px;
            border-radius: 50%;
            display: inline-block;
            background: gray;
            cursor: pointer;
        }
        ul>li.active{
            background: skyblue;
        }

JavaScript部分

var obj ={
                btns : document.getElementsByTagName("button"), 
				lis : document.getElementsByTagName("li"),
				imgs : document.getElementsByTagName("img"), 
                carous : document.getElementById("lunbo"),
				j : 0,
                timer:null,
                init:function(){// 初始化
                    this.bind();
                    this.kqdsq();
                },
                bind:function(){ // 绑定事件
                    var me= this;
                    for(var i=0;i<this.btns.length;i++){
                            this.btns[i].onclick=function(){
                            if(this.innerText==">"){
                                me.animate(1);
                            }else{
                                me.animate(-1);
                            }
                        }
                    }
                    for(var i=0;i<this.lis.length;i++){
                        this.lis[i].onclick=function(){
                            me.animate(0,this);
                        }
                    }
                    this.carous.onmouseover=function(){
                        me.tzdsq()
                    }
                    this.carous.onmouseout=function(){
                        me.kqdsq()
                    }
                },
                animate : function(num,b){ // 操作
                    this.clear();
                    if(num){
                        this.j+=num;
                        if(this.j==this.lis.length){
                            this.j=0;
                        }else if(this.j==-1){
                            this.j=this.lis.length-1;
                        }
                    }else{
                        this.j =parseInt(b.getAttribute("xb"));
                    }
                    this.lis[this.j].className="active";
                    this.imgs[this.j].className="active";
                },
                clear:function(){ // 清除样式
                    for(var i =0 ;i<this.lis.length;i++){
                        this.lis[this.j].className="";
                        this.imgs[this.j].className="";
                    }
                },
                kqdsq:function(){
                    var me=this;
                    this.timer=setInterval(function(){
                        me.animate(1)
                    },2000)
                },
                tzdsq:function(){
                    clearInterval(this.timer)
                }
            }

            obj.init();

1.强调: 1.属性名和方法名的引号其实可以省略,但是不建议,因为以后会学到一种数据 JOSN 要求属性名和方法名的双引号不能省略

2.如何访问对象的属性和方法: 对象名.属性名() 对象名.方法名() 对象名["属性名"] 对象名["方法名"] ()

2.特殊:1.访问到没有创建过的属性,返回undefined

2.随时随地可以添加不存在的属性和方法

3.通过for in 获取对象中的所有属性或者方法

for (var i in 自定义对象名){
    console.log(i)//拿到下标名称
    console.log(自定义对象名[i])//遍历取里面的值
}

4.如果你希望在对象的方法内部使用对象自己的属性,我们需要写为this.属性

this指向: 单个元素绑定事件this---这个元素

多个元素绑定事件this---当前元素

★★函数中的this---谁在调用此函数this就指向谁

定时器中的this--- 指向window

箭头函数this---指向外部对象

自定义构造函数中的this---指向当前创建的对象

2.构造函数方式: 不好用

创建: var obj=new object();

obj.属性名=属性值;

obj.方法名=function(){};

直接量方式和构造函数方式都只能创建单个对象

3.自定义构造函数方式:专门用于创建多个对象

创建:

function 类名(形参1,形参2,形参3....){  

            this.属性名1=属性值1; //属性名就是形参的名字

            this.属性名2=属性值2; this.属性名3=属性值3;

}

调用:

var obj=new 类名(实参1,实参2,实参3...);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值