学习JavaScript的第三周

128 阅读10分钟

一、正则表达式

  1. 定义:定义字符串中字符出现规则的表达式
  2. 语法:/正则表达式/
    1. 最简单的正则 语法:/no/后缀
    1. 备选字符集 语法:/^[备选字符集]$/ 注意:
  1. 一个中括号,只管一个字符
  2. 正则表达式默认只要满足就不管后续,如果要从头到尾完全匹配,前加"^",后加"$"
  3. 如果备选字符集中的ascii码是连续的,name可用“-”省略中间的部分
    1. 预定义字符集:提供定义了一些字符集,方便程序员简化备选字符集 语法:一位数字:\d,一位字母、数字、下划线:\w,一位空白字符:\s,一位除了换行外的任意字符:.

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

    1. 有明确数量:
字符集{n,m}:前边相邻的字符集,至少n个,最多m个
字符集{n,}:前边相邻的字符集,至少n个,多了不限
字符集{n}:前边相邻的字符集,必须n个
  • 2.没有明确数量:
?:前边相邻的字符集,可有可无,最多1个
*:前边相邻的字符集,可有可无,多了不限
+:前边相邻的字符集,至少1个,多了不限

4.选择和分组

  • 1.选择:在两个规则中选一个 规则1|规则2

  • 2.分组:将多个字符集临时组成一组子规则 (规则1|规则2)

  1. 指定匹配位置

^:开头

&:结尾

特殊:两者同时使用,前^,后&,表示从头到尾要求完全匹配

6.密码强度:4位密码,数字和字母的组合,至少出现一位数字和一位大写字母

语法:/^[0-9A-Za-z]{4}$/

7.预判公式

(?![0-9]+$) -> 不能全由数字组成
(?![a-z]+$) -> 不能全由小写字母组成
 (?![0-9a-z]+$) -> 不能全由数字、不能全由小写字母、不能只有他俩的组合组成
				
/(?![0-9a-z]+$)(?![A-Za-z]+$)[0-9A-Za-z]{4}/;//4位密码,数字和字母的组合,至少出现一位数字和一位大写字母
/(?![0-9a-z]+$)(?![A-Za-z]+$)(?![A-Z0-9]+$)[0-9A-Za-z]{4}/;//4位密码,数字和字母的组合,三者必须都有

二、支持正则表达式字符串的API:

1.切割

var arr=str.split(reg)

2.替换

  • 1.基本替换法 var newStr=str.replace(/正则/后缀,"新内容");
  • 2.高级替换法
		//a代表正则匹配到的当前的关键字
		return a.length==2?"**":"***";
			});

3.格式化

   var reg=/\d{6}(\d{4})(\d{2})(\d{2})\d{4}/;
			id=id.replace(reg,function(a,b,c,d){
				//在replace的时候,正则出现了分组:我们会得到更多的形参
				//在形参a的后面就会出现n个形参,就看你有多少个分组
				//第一个分组获得的内容会保存在第二个形参中
				//第二个分组获得的内容会保存在第三个形参中
				//...
				return b+"年"+c+"月"+d+"日";
			})
			console.log(id);

4.正则对象

    1. 创建:
直接量方式:var reg=/正则表达式/后缀;
构造函数方式:var reg=new RegExp("正则表达式","后缀");

  • 2.API:
var bool=reg.test(用户输入的内容);
true->验证成功 false->验证失败

三、Math对象:不需要创建,直接使用

1.API

  • 1.取整

1.上取整:超过一点点,就取下一个整数

var num=Math.ceil(num);//小数位数不能超过15位

2.下取整:无论超过多少,都会省略掉小数部分

var num=Math.floor(num);

3.四舍五入取整:

var num=Math.round(num);

4.乘方和开方

乘方:Math.pow(底数,幂); 
开方:Math.sqrt(num); 

5.最大值和最小值

var 最大/最小的=Math.max/min(a,b,c,d,e,....);

6.绝对值:把负数转为正数 Math.abs(-1);//1

7.随机数

Math.random();

公式:

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);

  • 4.复制一个日期: var end=new Date(start);

2.操作

  • 1.两个日期对象之间可以相减,得到一个毫秒差,换算出自己想要的某一部分 - 日期的本质其实就是保存的一个毫秒数 `创建方式:var date=new Date(毫秒数);

  • 2.API: getXXX/setXXX

特殊:

  1. 取值范围: FullYear:当前年份的数字 Month:0-11; Date:1-31 Day:0-6, Hours:0-23 Minutes Seconds:0-59

  2. Day,没有set方法

  3. 如果希望对某个分量进行加减计算

`date.setXXX(date.getXXX()+/-n)

` 4.格式化日期为字符串:

date.toLocaleString();

五、Error对象

  • 1.浏览器自带4种错误类型

1.语法错误:SyntaxError

2.引用错误:ReferenceError

3.类型错误:TypeError

4.范围错误:RangeError

  • 2.错误处理
try{
		可能出错的代码
	}catch(err){
		console.log(err);
		console.log("中文错误提示");
	}

  • 3.抛出自定义错误

throw new Error("自定义错误信息")

六、Function对象

1.创建

  • 声明方法:

function 函数名(形参,....){函数体;return 返回值;}

  • 直接量

var 函数名=function(形参,...){函数体;return 返回值;}

  • 构造函数

    var 函数名=new Function("形参1","形参2",....,"函数体;return 返回值;")

2.重载:相同的函数名,传入不同的实参,可以自动选择对应的函数执行操作

    1. arguments对象:只能在函数中使用,自动创建,是一个类数组对象
    1. 作用:接收所有传入的实参
    1. argument可以完成的事:(1)实现重载,通过在函数内部判断arguments,执行不同的操作(2)有没有形参无所谓(3)正式开发中,将多个函数整合为一个函数实现代码优化
  1. 匿名函数:没有名字的函数
  • 1.匿名函数自调:节约内存,匿名函数没有变量引用着,用完立刻释放 语法:(function(){}) ();

  • 2.匿名函数回调:讲函数作为实参,传递给其他函数调用

4,函数的执行原理

1.程序加载时:

  • 创建执行环境栈(ECS):保存函数调用顺序的数组 首先压入全局执行环境(全局EC) 全局EC引用着全局对象window window中保存着全局变量
  1. 定义函数时:
  • 创建函数对象:封装代码段 在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里 全局函数的scope都是window
  1. 调用前:
  • 在执行环境栈(ECS)压入新的EC(函数的EC) 创建活动对象(AO):保存着本次函数调用时用到的局部变量 在函数的EC中有一个scope chain(作用域链)属性引用AO AO有一个parent属性是函数的scope引用着的对象

4.调用时:

  • 因为前三步,有了变量的使用规则:优先使用自己的,自己没有找全局,全局没有报错

5.调用完:

  • 函数的EC会出栈,AO会自动释放,局部变量也自动释放了
  1. 两链一包:作用域链、原型链、闭包
    1. 作用域链:以函数的EC的scope chain属性为起点,经过AO,逐级引用,形成一个链式结构
    1. 原型链:每个对象都有一个属性:proto,可以一层一层的找到每个人的父亲,形成的一条链式结构,就称为原型链
    • 最顶层是object的原型,上面放着to string,js万物皆对象,人人都能用to string();
    1. 闭包:保护一个可以反复使用的局部变量的一种词法结构
  • 使用:1.两个函数进行嵌套 2.外层函数创建出受保护的变量 3.外层函数把return出内层函数 4.内层函数要去操作受保护的变量 缺点:受保护的变量永远都不会被释放,使用过多,内存泄漏
  1. 防抖节流
  • 1.三个需要防抖节流的事件

(1)鼠标移动事件: elem.onmousemove (2)每次输入/改变就会触发: input.oninput (3)每次窗口大小发生变化就会触发 window.onresize

  • 公式
elem.on需要防抖节流的事件=function(){
				fdjl();//内层函数只要一旦移动就会触发
			}

			function f1(){
				var timer=null;//3
				return function(){//
					if(timer){clearTimeout(timer);timer=null;}
					timer=setTimeout(function(){
						//操作
					},1000)
				}
			} 
			
			var fdjl=f1();
                        
     

七、Object:面向对象:三大特点:封装、继承、多态

  1. 开发方式:面向对象和面向过程
  • 面向过程:经过-开始-结束,开发方式都是面向过程,决定先干什么再干什么最后干什么

  • 面向对象:对象(属性和方法)

2.封装:创建自定义对象

  • 1.直接量方法`var obj={ "属性名":属性值, ... "方法名":function(){}, ... }

  • 2.访问对象的属性和方法: obj.属性名 obj.方法名()

  • 3.遍历数组:for in,obj[i] 才能拿到

  • 4.希望在对象的方法里使用对象自己的属性:this.属性名

  • 5.this的指向:

  • 单个元素绑定事件:this->单个元素

  • 多个元素绑定事件:this->当前触发的元素

  • 函数中使用this:this->谁在调用此方法,this值的就是谁

  • 定时器中的this:this->window

  • 2.预定义构造函数方式var obj=new Object(); //需要自己后续慢慢追加属性和方法 obj.属性名=属性值 obj.方法名=function(){}

  • 3.自定义构造函数方法

  1. 创建自定义构造函数:

function 类名(name,age,salary){
				this.name=name;
				this.age=age;
				this.salary=salary;
			}

2.调用构造函数创建出对象 var obj=new 类名(实参1,...)

  • 优点:所有的属性和方法都保存在一个对象中,每个功能特地分开写,便于维护

4.继承:父对象的成员(属性和方法),子对象可以直接使用

  • 1.何时使用:只要多个子对象公用的属性和方法,都要集中定义在父对象中

  • 2.找原型对象(父对象):保存一类子对象共有属性和共有方法的原型对象

      1. 对象名.__proto__;
    • 2.构造函数名.prototype;//构造函数名,几乎人人都有,除了Math
  • 3.设置共有的属性和方法

  1. 添加一个共有属性: 原型对象.属性名=属性值;

  2. 添加一个公有方法: 原型对象.方法名=function(){};

  3. 判断是自有还是共有

    1. 判断自有:结果为true为自有属性,false可能是共有或者没有 obj.hasOwnProperty("属性名");
  • 2.判断共有

if(obj.hasOwnProperty("属性名")==false && "属性名" in obj){//in 会自动在obj的原型上进行查找
					共有
				}else{
					没有
				}


公式:

if(obj.hasOwnProperty("属性名")){//false
				console.log("自有")
			}else{  
				if("属性名" in obj){
					console.log("共有")
				}else{
					console.log("没有")
				}
			}
  • 3.删除自有和共有

  • 自有 `` 修改:obj.属性名; 删除:delete obj.属性名;

  • 共有:找到原型再删除/修改

  • 4.如何判断x是不是一个数组:不能用typeof,typeof只能检查原始类型,不能检查引用类型

  • (1)判断X是否继承自Array.prototype Array.prototype.isPrototypeOf(x);

  • (2)判断X是不是由Array这个构造函数创建 x instanceof Array;

-(3)x instanceof Array;->仅数组能用

  • (4) 输出对象的字符串形式

  • 多态:子对象觉得父对象的成员不好,在本地定义了同名成员,覆盖了父对象的成员

借用:Object.prototype.toString.apply(x);
				if(Object.prototype.toString.apply(arr)=="[object Array]"){
					console.log("是数组")
				}else{
					console.log("不是数组")
				}

  • 5.为老IE的数组添加indexOf
if(Array.prototype.indexOf===undefined){//老IE
				Array.prototype.indexOf=function(key,starti){
					starti==undefined&&(starti=0);
					for(var i=starti;i<this.length;i++){
						if(this[i]==key){
							return i;
						}
					}
					return -1;
				}
			}

实现自定义继承

1.两个对象之间设置继承 子对象.__proto__=父对象

2.多个对象之间设置继承 构造函数名.prototype=父对象