一.字符串的API★★★★★
转义字符:\
在字符串之中出现了和程序冲突的字符时使用
比如:希望在双引号之中在放入一个双引号,在单引号中放入单引号
"\"" '\''
特殊功能的转义字符
\n 换行
\t 制表符:相当于tab出来的大空格
可以书写unicode号代表的字
\uXXXX 输出某一个字
汉字的第一个字:\u4e00
汉字的最够一个字:\ u9fa5
★英文转大小写:
统一的将字符串转为大写或者小写,再比较,忽略大小写(验证码)
大写 var upper=str.toUpperCase();
小写 var lower=str.toLowerCase();
获取字符串中的某一个字符:
str.CodeAt(); === str[i];
获取字符串中的每一个字符的ASCII码:
var ascii=str.charCodeAt(i);
通过ASCII码转回原文:
var tex=String.fromcharCode();
::selection{background:transparent;}设置文字双击后的选择颜色
检索字符串:检查索引/下标
使用:判断有没有,不重复
var i = str.indexOf("关键字",start i);
特殊:
1.start i可以省略
如果省略默认从0位置开始向右查找
2.返回:
如果找到了,返回关键字的第一个字符的下标
★★★没找到返回-1,重点:我们不关系下标为多少,只关心下标是不是-1,为-1就是说明没有,如果不为-1,说明存在
3.数组也可以使用:
其实以前的数组没有这个方法,某浏览器更新后,数组才可以使用(老IE浏览器(ie8一下的)用不到)
4.笔试题:
知道所有关键字的下标
var str="no zuo no dai no can no bb";
var index=-1;
while((index=str.indexOf("no",index+1))!=-1){
console.log("下标为"+index);
}p
5.拼接字符串 :
var newStr=str.concat(str1,str2.....);还不如 + 连接字符串
6.★截取字符串:3种
★1. var subStr=str/arr.slice(start i,end i+1);
2.var subStr=str.subString(start i,end i+1); 几乎和slice一致,但是不如slice,因为不支持负数的参数
★3. var subStr=str.substr(start i,n) 截取的个数,不必考虑含头不含尾
7.★替换字符串
var newStr=str.replace("固定关键字"/RegExo,"新内容");
这个方法很厉害,目前没学过正则表达式,所以替换暂时只能替换一个固定关键字,比较low
8.★★★★★切割/分隔字符串:功能:字符串<=>数组
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]
一个汉字[\u4eoo-\u8fa5]
除了xxx之外,其他都可以
[^xxx]-范围广,不推荐
预定义字符集:前辈们提前定义了一些常用的字符集
一个数字:\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-Za-z]{4,6}$/ 只能输入一个数字和大写字母组成的4-6位密码
★★★★★字符串支持正则的API
切割
var a = string.split("固定切割符")
替换
基础替换:var a = string.replace(“关键字”,"新值")
★★
var str="卧槽,我操,我草,握草,卧草,我曹,窝草,窝槽,我去操"
str.replace(/[我卧握窝][草曹操]+/g,"**")
高级替换:
str=str.replace(/[我卧握窝][去槽操曹草]+/g,function(key,i,str){//此回调函数会自动调用,找到几个关键字就会执行几次
// console.log(key);//当前次正则匹配到的关键字
// console.log(i);//当前次正则匹配到的关键字的下标
// console.log(str);//原文本身
return key.length==2?"**":"***";
});
格式化
如果替换式,正则中,带有分组,那么你的回调函数会由更多的形参
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.onsubmit=function(){}
Math:专门用于提供数学计算的API
强调:不能,不需要创建,浏览器自带的
属性:Math.PI
API:
向上取整:Math.ceil()
向下取整:Math.floor()
四舍五入:Math.round()
固定精度:Math.toFixed() 缺点:返回的是字符串 用parseFloat包起来
固定长度:Math.toPrecision()
取整:Math.parseInt()、位运算
乘方,开方
*乘方:Math.pow(底数,幂)
开放:math.sqrt()
最大值,最小值
Math.max()
Math.min()
缺陷:不支持传入数组参数,不能比较数组的最大值和最小值
解决:Math.max/min.apply(Math,arr);
apply可以悄悄打散数组,将每一个元素单独传入--ES5带来的特性
apply可以借用方法
笔试题:比较出数组中的最大值和最小值(2 种方法) for循环遍历比较,Math.max.apply(Math,arr)
绝对值:
Math.abs();
随机数:
parseInt(Math.randow()*(max-min+1)+min);随机整数
Math.random(); 默认0-1之间取随机数
可以取到0,但不可能取到1
在min和max之间取随机数
parseInt(Math.random()*(101)); 可以取最大值
parseInt(Math.random()*(100)+1); 可以取最小值以及最大值
笔试题:
封装自定义函数,按照任意小数位四舍五入,返回数字类型
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对象
1.浏览器自带4中错误类型,可以快速找到错误
EvalError(eval错误)
3 RangeError(范围错误)
4 ReferenceError(引用错误)
5 SyntaxError(语法错误)
6 TypeError(类型错误)
7 URIError(URI错误)
SyntaeError——语法错误:符号或者语法错了
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....错误提示可以用:
-
throw new Error("XXX");
-
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.onresize=function(){
return inner();
}
function fdjl(){
var timer;
return function () {
if (timer) {
clearTimeout(timer);
}
timer=setTimeout(function(){
函数体;(需要做的操作)
},时间)
}
}
}
var inner=fdjl();//inner()内层函数才是写在事件中的操作
Object面向对象开发方式
三大特点:封装,继承,多态
面试题:简单说一下你了解的面向过程和面向对象 开发方式的区别?
面向过程:开始--经过--结束,从一开始学习到学习写法都是面向过程
面向对象:对象(属性和方法),如果这个世界有各种属性和各种方法,但是练一个对象/生物都没有,那些对象就没有具体意义
创建自定义对象:
1.直接量方式:
var obj={
"属性名1":属性值1,
"属性名2":属性值2,
.....
"方法名":function(形参1...){函数体};
}
1.强调:
1.属性名和方法名的引号其实可以省略,但是不建议,因为以后会学到一种数据 JOSN 要求属性名和方法名的双引号不能省略
2.如何访问对象的属性和方法: 对象名.属性名() 对象名.方法名() 对象名["属性名"] 对象名["方法名"] ()
3.特殊:
1.访问到没有创建过的属性,返回undefined
2.随时随地可以添加不存在的属性和方法
3.通过for in 获取对象中的所有属性或者方法
for (var i in 自定义对象名[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...);
\