什么是: 连续存储多个字符的字符数组
相同: 1. 下标 2. .length 3. 遍历前端
4. 选取: slice(starti[, endi])
不一样: 类型不一样 API不通用
API: 全部字符串API都无权修改原字符串,老是返回新字符串正则表达式
说明: 验证码本不应客户端作,应该由服务器端完成数据库
str.charAt(i) => str[i]
获取指定位置字符的unicode号
str.charCodeAt(i)小程序
将unicode号转为汉字: String.fromCharCode(unicode)
str.slice(starti,endi+1)
强调: 若是一个API,两个参数都是下标,则后一个参数+1(含头不含尾)
str.substring(starti,endi+1) 用法和slice彻底同样
强调: 不支持负数参数
str.subStr(starti,n) 从starti开始,取n个
强调: 第二个参数不是下标,因此,不用考虑含头不含尾数组
var i=str.lastIndexOf("关键词");
在str中,查找"关键词"最后出现的位置promise
问题: 只能查找一个固定的关键词
卧我草/操/艹/槽
微 信 w x wei xin
解决: 用正则查找:浏览器
判断是否包含关键词:
var i=str.search(/正则/)
返回值: 若是找到,返回关键词的位置服务器
若是没找到,返回-1
问题: 默认,全部正则都区分大小写
解决: 在第二个/后加i ignore 忽略
问题: 只能得到位置,没法得到本次找到的敏感词的内容网络
得到关键词的内容:
var arr=str.match(/正则/i);
2种状况:闭包
强调: 若是找不到,返回null
警告: 凡是一个函数可能返回null!都要先判断不是null,才能用!
问题: 只能得到关键词内容,没法得到位置
什么是: 将找到的关键词替换为指定的内容
如何: 2种:
高级替换: 根据每一个敏感词的不一样,分别替换不一样的值
str=str.replace(/正则/,function(kw){
//kw: 会自动得到本次找到的一个关键词 return 根据kw的不一样,动态生成不一样的替换值
})
衍生: 删除关键词:
str=str.replace(/正则/,"")
什么是: 描述一个字符串中字符出现规律的规则的表达式
什么时候: 2种:
如何: 正则表达式语法:
什么是: 规定一位字符,备选字符列表的集合
什么时候: 只要一位字符,有多种备选字时
如何: [备选字符列表]
强调: 一个[]只能匹配一位字符
简写: 若是备选字符列表中部分字符连续
可简写为: [x-x] 用-省略中间字符 好比: [0-9] 一位数字 [a-z] 一位小写字符 [A-Z] 一位大写字母 [A-Za-z] 一位字符 [0-9A-Za-z] 一位字母或数字 [\u4e00-\u9fa5] 一位汉字
反选: 1 除了4和7都行
d 一位数字 [0-9]
w 一位数字,字母或下划线 [0-9A-Za-z_]
强调: 只有100%匹配时,才使用w,若是不容许有_,则使用自定义字符集
s 一位空字符,好比: 空格,Tab,...
. 通配符
问题: 字符集只能规定字符的内容,没法灵活规定字符的个数
什么是: 专门规定一个字符集出现次数的规则
什么时候: 只要规定字符集出现的次数,都用量词
如何: 字符集量词
强调: 量词默认只修饰相邻的前一个字符集
包括: 2大类:
1. 有明确数量边界: {6,8} 最少6次,最多8次 {6,} 最少6次,多了不限 {6} 必须6次,不能多也不能少 2. 没有明确数量边界: ? 无关紧要,最多1次 * 无关紧要,多了不限 + 至少1次,多了不限
分组: (规则1规则2...)
什么时候: 若是但愿一个量词同时修饰多个规则时,都要先将多个规则分为一组,再用量词修饰分组。
好比: 车牌号: [\u4e00-\u9fa5][A-Z]•[0-9A-Z]{5} 好比: 手机号规则: \+86或0086 无关紧要,最多1次 空字符 无关紧要,多了不限 1 在3,4,5,7,8中选一个
9位数字
(+86|0086)?s*1[34578]d{9}
好比: 身份证号:
15位数字 2位数字 一位数字或X
无关紧要,最多一次 \d{15}(\d{2}[0-9X])? 好比: 电子邮件: 鄙视
/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
好比: url:
(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
字符串结尾: $
好比: 开头的空字符: ^s+
结尾的空字符: \s+$ 开头或结尾的空字符: ^\s+|\s+$
3.单词边界: b 包括开头,结尾,空字符,标点符号
好比: 单词首字母: \b[a-z] 匹配单词: \bxxx\b
替换: 2种: 若是关键词是固定的:
str=str.replace("关键词","替换值");
若是关键词变化
str=str.replace(/正则/ig,"替换值");
切割: 2种: 若是分隔符是固定的:
var substrs=str.split("分隔符")
若是分隔符不是固定的
var substrs=str.split(/正则/i)
固定套路: 将字符串打散为字符数组
var chars=str.split("")
什么是: 保存一条正则表达式,并提供用正则表达式执行验证和查找的API
什么时候: 只要用正则查找关键词或验证字符串格式时
如何:
建立: 2种:
API: 2个:
什么是: 保存数学计算的常量和API的对象
什么时候: 进行算术计算
如何:
建立: 不用建立,全部API都用Math直接调用
API:
三角函数:
已知角度,求边长,用三角函数: sin cos tan
已知边长,求角度,用反三角函数: asin acos atan
仅以atan:
var 弧度=Math.atan(对边长/邻边长)
360角度=2π弧度
问题: atan没法区分角度的象限
解决: Math.atan2(对边长, 邻边长);
什么是: 保存一个时间,提供操做时间的API
什么时候: 只要在程序中存储时间或操做时间,都用date
如何:
建立: 4种:
本质: 起始日期对象内部保存的是一个巨大的毫秒数:
1970年1月1日至今的毫秒数
文字存储日期的问题:
1. 有时区问题: 2. 不便于计算:
毫秒数存储日期:
1. 不受时区的干扰: 2. 便于计算:
总结: 未来在网络中传输或在数据库中存储时间,都用毫秒数
日期计算:
对任意单位作加减: 3步:
可简化为: date.setXXX(date.getXXX()+n)
问题: setXXX()直接修改原日期
解决: 若是同时保存计算先后的开始和结束时间,应该先复制副本,再用副本计算。
日期格式化:
date.toString() 默认当地时间的完整版格式
date.toLocaleString() 转为当地时间的简化版格式
date.toLocaleDateString() 仅保留日期部分
date.toLocaleTimeString() 仅保留时间部分
什么是错误: 程序执行过程当中,遇到的没法继续执行的异常状况
程序出错,都会强行中断退出。
什么是错误处理: 即便程序出错!也保证不会中断退出
什么时候: 若是但愿程序,即便出错,也不会强行中断退出
如何:
try{
可能出错的正常代码
}catch(err){
//err: 错误对象, 自动保存了错误的信息
只有出错才执行的错误处理代码:
提示错误信息, 记录日志, 释放资源
}
问题: 效率略低
解决: 多数try catch,都能用if...else代替
主动抛出错误:
throw new Error("错误信息")
鄙视: js中共有几种错误类型: 6种:
SyntaxError 语法错误
ReferenceError 引用错误
TypeError 类型错误
RangeError 范围错误 参数超范围
EvalError URIError
什么是函数: 保存一段代码段的对象,再起一个名字。
为何: 代码重用
什么时候: 只要一段代码可能被重复使用时!
如何:
建立: 3种:
声明: function 函数名(参数列表){
函数体; return 返回值; }
参数: 调用函数时,接收传入函数的数据的变量
什么时候: 若是函数自身必须某些数据才能正常执行时,就必须定义参数,从外部接收必须的数据
返回值: 函数的执行结果
什么时候: 若是调用者须要得到函数的执行结果时
调用: var 返回值=函数名(参数值列表);
问题: 声明提早: 在程序开始执行前,先将var声明的变量和function声明的函数,提早到当前做用域的顶部集中建立。赋值留在原地。
解决:
直接量: var 函数名=function (参数列表){
特色: 不会被声明提早
揭示: 函数名其实只是一个变量
函数实际上是一个保存代码段的对象 函数名经过对象地址引用函数对象
什么是: 多个相同函数名,不一样参数列表的函数,在调用时,可根据传入的参数不一样,自动执行不一样的操做。
为何: 为了减小API的数量,减轻调用者的负担
什么时候: 只要一项任务,可能根据传入参数的不一样,执行不一样的流程时。
如何: js语法默认不支持重载!
由于: js中不容许多个同名函数,同时存在。最后一个函数会覆盖以前的。 变通实现: arguments 什么是: 每一个函数中,自动包含的,接收全部传入函数的参数值的类数组对象 类数组对象: 长得像数组的对象 vs 数组: 相同: 1. 下标, 2. .length, 3. 遍历 不一样: 类型不一样, API不通用
什么是: 定义函数时,不指定函数名
为何: 节约内存 或 划分临时做用域
什么时候:
如何:
什么是垃圾: 一个再也不被任何变量使用的对象
什么是垃圾回收: js引擎会自动回收再也不被使用的对象的空间。
为何: 内存空间都是有限的!
垃圾回收器: 专门负责回收垃圾对象的小程序——js引擎自带
如何:
好的习惯: 只要一个对象再也不使用,就要赋值为null
做用域(scope): 一个变量的可用范围
为何: 避免内部的变量影响外部
本质: 是一个存储变量的对象
包括: 2种:
程序开始执行前
在内存中建立执行环境栈(数组): 用于保存正在调用的函数任务。
在执行环境站中添加第一条记录: 调用浏览器主程序
建立全局做用域对象window: 2个做用:
1. 保存浏览器本身须要的数据和对象 2. 做为程序的全局做用域对象,保存全局变量
什么是: 由多级做用域对象,逐级引用造成的链式结构
2个做用:
什么是: 即重用一个变量,又保护变量不被污染的一种机制
为何: 全局变量和局部变量都具备不可兼得的优缺点:
全局变量: 优: 可重用, 缺: 易被污染
局部变量: 优: 仅函数内可用,不会被污染
缺: 不可重用!
什么时候: 只要一个变量,可能被重用,又不想被篡改
如何: 3步:
闭包造成的缘由: 外层函数调用后,外层函数的函数做用域对象没法释放
主动使用闭包: 为一个函数绑定一个专属的变量
鄙视: 画简图
找内层函数对象
外层函数向外返回内层函数对象: 3种:
什么是对象: 内存中存储多个数据的独立存储空间都称为一个对象。
什么是面向对象: 程序中都是用对象结构来描述现实中一个具体事物。
为何: 为了便于大量数据的维护和查找
什么时候: 几乎全部js程序,都使用面向对象的方式开发
如何: 三大特色: 封装,继承,多态
封装: 用对象来集中描述现实中一个具体事物的属性和功能
为何: 便于维护和查找
什么时候: 从此只要使用面向对象的方式开发,都要先封装对象,再按需使用对象的属性和功能。
如何: 3种:
用{}:
var obj={
属性名:值,
... : ... ,
//方法名:function(){...},
方法名 (){...},
}
其中: 事物的属性值会成为对象的属性
对象的属性本质是保存在对象中的一个变量 事物的功能会成为对象的方法! 方法的本质是保存在对象中的一个函数
如何访问对象的成员:
访问对象的属性: 对象.属性名
调用对象的方法: 对象.方法名()
问题: 对象本身的方法中要使用对象本身的属性
错误: 直接用属性名,报错: 找不到变量
为何: 默认,不加.就使用的变量,只能在做用域链中查找,没法自动进入对象中
解决一: 对象名.属性名
问题: 对象名仅是一个普通的变量名,可能发生变化。
正确解决: this.属性名
this: 自动指正在调用当前方法的.前的对象
为何: 不受对象名变量的影响 什么时候: 只要对象本身的方法向访问对象本身的属性时,都必须加this.
js中对象的本质,其实就是一个关联数组
和关联数组同样,js中的对象也可随时添加新属性和方法。
问题: 反复建立多个相同结构的对象时,重复代码太多,致使不便于维护
解决:
用构造函数:
构造函数: 描述一类对象统一结构的函数
为何: 为了重用结构代码!
什么时候: 只要反复建立相同结构的多个对象时,都用构造函数
如何: 2步:
定义构造函数
function 类型名(属性参数列表){
this.属性名=属性参数;
this. ... = 属性参数;
this.方法名=function(){
this.xxx
}
}
调用构造函数建立新对象
var obj=new 类型名(属性值列表)
new: 1. 建立新的空对象
2. 设置新对象继承构造函数的原型对象 3. 用新对象调用构造函数 将构造函数中的this都指向新对象 4. 返回新对象的地址
问题: 构造函数只能重用代码,没法节约内存!
解决: 继承:
什么是: 父对象的成员,子对象无需建立,就可直接使用
为何: 代码重用,节约内存
什么时候: 只要多个子对象,拥有相同的成员时,都应只在父对象中定义一份,全部子对象共用便可!
如何: js中继承都是经过原型对象实现的
什么是原型对象: 集中存储同一类型的全部子对象,共用成员的父对象 什么时候: 只要继承,必然原型对象 如何: 建立: 不用建立,买一赠一 每建立一个构造函数,都附赠一个原型对象 继承: 在建立子对象时,new的第2步自动设置子对象继承构造函数的原型对象 访问成员: 优先访问自有成员 本身没有,就去父对象(原型对象)中查找 将成员添加到原型对象中: 构造函数.prototype.成员=值
自有属性和共有属性:
自有属性: 保存在当前对象本地,仅归当前对象独有的属性
共有属性: 保存在父对象中,全部子对象共有的属性
读取属性值: 子对象.属性
修改属性值: 自有属性,必须经过子对象本身修改
共有属性,只能用原型对象修改!
内置对象的原型对象:
鄙视: 内置对象: 11个:
String Number Boolean ——包装类型对象 Array Date RegExp Math Error Function Object Global (在浏览器中,被window代替)
鄙视: 包装类型的理解
什么是: 保存一个原始类型的值,并提供操做原始类型值的API 为何: 原始类型的值自己不具备任何功能 什么时候: 只要试图对原始类型的值调用API时,都会自动使用包装类型对象来帮助原始类型的值执行操做。 如何: 1. 内存中已经预置了三大包装类型的对象: String Number Boolean 2. 在试图对原始类型的值调用API时,自动检测原始类型的值的类型名 var n=345.678; typeof n => number 3. 根据类型名实例化对应的包装类型对象,调用其API new Number(n).toFixed(2) => 345.68 4. 执行后,包装类型对象自动释放 new Number释放!
面向对象三大特色: 封装,继承,多态
继承:
原型对象:
内置类型的原型对象:
一种类型: 包含两部分:
1. 构造函数: 建立该类型的子对象 2. 原型对象: 保存全部子对象的共有成员
解决浏览器兼容性问题: 旧浏览器没法使用新API
1. 判断当前浏览器对应类型的原型对象中是否包含该API 2. 若是不包含,则自定义该API,添加到对应类型的原型对象中
什么是: 由多级父对象,逐级继承造成的链式结构
保存着: 全部对象的属性
控制着: 对象属性的使用顺序:
先自有,再共有
鄙视: 如何判断一个对象是数组类型? 有几种方法
错误: typeof : 只能区分原始类型,函数,没法进一步区分引用类型对象的具体类型名
正确: 4种:
问题: 不严格, 不但检查直接父对象,且检查整个原型链
class属性: 对象内部的专门记录对象建立时的类型名的属性
问题1: class属性是内部属性,没法用.直接访问
解决: 惟一的办法: Object.prototype.toString()
问题2: 每种类型的原型对象都重写了各自不一样的toString()方法,子对象没法调用到Object.prototype.toString()
解决: fun.call(obj) 让obj强行调用任何一个fun
Object.prototype.toString.call(obj) 在执行的一瞬间: obj.toString() 结果:"[object Class]"
鄙视: 什么时候将方法定义在原型对象中,什么时候将方法定义在构造函数上
实例方法和静态方法:
实例方法: 必须该类型的子对象才能调用的方法
好比: arr.sort() arr.push()
什么时候: 只要要求必须该类型的子对象才能调用
如何: 全部放在原型对象中的方法都是实例方法
静态方法: 不须要建立该类型的子对象,任何对象均可使用的方法。
好比: Array.isArray(fun)
Array.isArray(date) Array.isArray(obj)
什么时候: 不肯定未来调用该函数的对象类型时
如何: 添加到构造函数对象上的方法都是静态方法。可经过构造函数.静态方法方式直接调用!
什么是: 一个方法在不一样状况下表现出不一样的状态
包括:
两种类型间的继承:
什么时候: 发现多个类型之间拥有部分相同的属性结构和方法定义时,都要抽象父类型出来
如何: 2步:
定义抽象父类型: 2步:
让子类型继承父类型: 2步:
严格模式:
什么是: 比普通js运行机制要求更严格的模式
为何: 普通的js运行机制有不少广受诟病的缺陷
什么时候: 从此全部项目必须运行在严格模式下
如何:
规则: 4个:
补: arguments.callee 自动得到当前正在调用的函数自己
禁用,说明强烈不推荐使用递归!
保护对象的属性:
ES5将对象属性分为:
命名属性: 可用.直接访问到的属性
数据属性: 直接存储属性值的属性
保护数据属性: 4大特性:
一个属性包含四大特性:{ value: 实际保存属性值, writable: true/false, //只读 enumerable: true/false, //不可遍历 //不是完全隐藏,用.依然可访问! configurable:true/false //1. 禁止删除 //2. 禁止修改其它特性 //一旦改成false,不可逆 } 获取一个属性的四大特性: var attrs=Object.getOwnPropertyDescriptor(obj,"属性") 修改四大特性: Object.defineProperty(obj,"属性",{ 四大特性:值 }) 简写: Object.defineProperties(obj,{ 属性名:{ 特性:值, 特性:值, }, 属性名:{ ... : ... } })
访问器属性: 不直接存储属性值,仅提供对另外一个数据属性的保护
什么时候: 只要对一个属性提供自定义规则的保护
如何:
添加: 只能用Object.defineProperty和defineProperties添加 四大特性: { get(){ return this.数据属性 } set(val){ 若是验证val经过 this.数据属性=val 不然 报错 } enumerable: configurable: }
如何使用: 同普通的数据属性用法同样!
在取值时,自动调用访问器属性内部的get 在赋值时,自动调用访问器属性内部的set方法,同时将等号右边的新值,交给val参数
问题: enumerable只能防住for in,防不住.,依然可用.直接修改被保护的数据属性
解决:
内部属性: 不能用.直接访问到的属性
好比: class proto
保护对象的结构: 3种
防扩展: 禁止给对象添加新属性
Object.preventExtensions(obj)
原理: 内部属性: extensible:true
preventExtensions将extensible改成false
密封: 在防扩展同时,禁止删除现有属性
Object.seal(obj)
原理: 1. 将extensible改成false,禁止扩展
2. 自动将全部属性的configurable都改成false
冻结: 在密封的同时,禁止修改一切属性值
Object.freeze(obj)
原理: 1. 兼具密封的全部功能
2. 又将每一个属性的writable自动改成false!
Object.create()
仅用父对象,就可建立子对象,
同时还可为子对象扩展自有属性
var child=Object.create(father,{
//Object.defineProperties
属性名:{
特性:值, 特性:值,
}
})
鄙视: 描述Object.create的执行原理
替换函数中不想要的this!
call/apply: 马上调用函数,并临时替换中的this为指定对象
什么时候: 只要调用函数时,函数中的this不是想要的就用call换成想要的
若是传入函数的参数,是以数组形式,总体传入
就用.apply(obj,arr)
bind: 基于原函数,建立一个新函数,并永久绑定this为指定对象
什么时候: 不会马上调用的函数(回调函数)中的this,不是想要的,就可用bind建立一个新函数,并永久绑定this!
判断:
判断数组中全部元素是否都符合条件
arr.every(function(elem,i,arr){
//elem: 当前元素值 //i: 当前位置 //arr: 当前数组对象 return 判断条件
})
判断数组中是否包含符合条件的元素
arr.some(function(elem,i,arr){
return 判断条件
})
遍历:
过滤和汇总:
为何
问题1: 声明提早, 破坏程序原有执行顺序
解决: let禁止在声明以前,提早使用该变量
问题2: js没有块级做用域, 块内的变量,会污染到块外
解决: let会将当前所在if/for/while...(){}变成块级做用域
后果: 块内的let出的变量不会影响外部!
原理: 其实let就是匿名函数自调!
let与for循环,可造成闭包的效果
强调: 原来块内外均可使用的变量,出了块,就不能用了!
默认值: function fun(参数1, 参数2,...,参数n=默认值)
强调: 带默认值的参数必须定义在列表末尾
原理: 参数n=参数n||默认值;
rest: 代替了arguments
什么时候: 当函数,不肯定参数个数时——重载
为何: arguments的缺点:
如何: 定义函数时: function fun(参数1,参数2,..., ...数组名)
数组名, 是一个纯正的数组,且可有选择的分段获取
原理: var arr=[].slice.call(arguments[,starti]);//将类数组对象转为数组
spread: 代替apply
为何: apply虽然可打散数组类型参数为单个值,可是必须和替换this的操做捆绑使用
什么时候: 只要仅须要打散数组类型参数为单个值时
如何: 调用时: fun(参数值1,参数值2,...数组)
什么时候: 只要回调函数,都再也不使用function,而是使用箭头函数
如何:
若是函数体只有一句话,则{}可省略
更简化: 若是仅有的一句话仍是return,可省略return
特色: 内外共用同一个this ——代替bind
问题: 若是反而但愿内外this不通用时,就不能用箭头函数
ESLint规定,不容许使用+拼接字符串
如何:
什么是: 将一个对象/数组中的成员和元素,分别提取出来,单独使用。
为何: 避免反复使用对象名/数组名
什么时候: 只要但愿将一个大的对象或数组中的每一个成员单独取出使用时
如何: 3种:
什么是: 依次遍历数组/类数组对象中每一个元素的值
vs for...in: 依次遍历关联数组/对象中每一个成员的属性名
什么时候: 若是但愿从头至尾遍历整个数组或类数组对象
如何:
for(var elem of arr){ elem }
局限: 没法得到当前位置; 没法控制遍历的进度/顺序; 没法有选择的遍历部分
封装:
class Student { constructor(sname,sage){ ... ... } intr (){//Student.prototype.intr } fun (){ } }
继承:
class Flyer { constructor(fname,speed){ ... ... } fly (){ ... ... } } class Plane extends Flyer{ constructor(fname,speed,score){ //super指向父类型构造函数,且自动替换this super(fname,speed) ... ... } getScore (){ ... ... } }
静态方法:
class User{ constructor(uname,upwd){ this.uname=uname; this.upwd=upwd; } save(){//保存在User.prototype中的实例方法 console.log("保存当前对象"); } static findOne(){//静态方法,定义在构造函数上 return new User(); } } var user=new User(...); user.save();//调用实例方法 User.findOne();//调用静态方法
什么是callback hell: 因为使用参数传递回调函数,致使步骤多时,参数的嵌套层级很深。
什么时候: 只要异步调用,可能发生延迟时,都要用Promise代替传统参数callback
如何: 定义时
function 第一件事(){ return new Promise(fn=>{ 第一件事的内容 fn() }) } function 第二件事(){ return new Promise(fn=>{ 第二件事的内容 fn() }) } function 第三件事(){ 第三件事的内容 }
调用时:
第一件事()//return Promise(fn) .then(第二件事)//return Promise(fn) .then(第三件事)
鄙视题:
将类数组对象复制为数组:
var arr2=Array.prototype.slice.call(arguments)
将类数组对象复制为数组,并选取指定位置的剩余元素
var arr2= Array.prototype.slice.call(arguments,starti)
至关于arguments.slice(starti)
其实更简单的: var arr2= [].slice.call(arguments,starti)
promise中的错误处理:
其实: new Promise(可接收2件事)
.then( ) .catch( )
new Promise((正常函数,出错函数)=>{
若是顺利执行: 调用正常() 不然 调用出错()
})
等待多个任务完成
前提: 每一个任务都必须都返回Promise
如何: Promise.all([
task1(), task2(),... ]).then(()=>{全部任务完成后才执行的任务})