安装 安装visual studio codejava
安装visual studio code插件正则表达式 |
正则表达式概述(Regular Expression)算法 专门描述字符串中字符出现规则的表达式。sql |
1.正则表达式可用于:1).验证字符串格式编程 2).查找敏感词json |
2.字符集简写:若是[]中部分备选字符连续,可用-省略中间字符数组 好比:[0123456789]可简写为[0-9]promise 要匹配一位小写字母:[a-z]浏览器 要匹配一位字母[A-Za-z] 匹配一位字符或者数字:[0-9A-Za-z] 要匹配一位汉字:[\u4e00-\u9fa5] |
3.预约义字符集正则表达语法为四种经常使用的字符集定义了最简化写法,称为预约义字符集。
|
1.查找:1). 查找一个固定的关键词出现的位置: var i=str.indexOf("关键词"[,starti]) 在str中从starti位置开始找下一个"关键词"的位置 若是省略starti,则默认从0位置开始向后找 返回: “关键词”第一字所处位置的下标 若是找不到,返回-1 问题: 只支持查找一个固定不变的关键词
|
2. 用正则表达式查找一个关键词的位置:var i=str.search(/正则/i); 在str中查找符合"正则"要求的敏感词 返回值: 关键词的位置 若是找不到,返回-1 问题: 正则默认区分大小的! 解决: 在第2个/后加后缀i,表示ignore,意为:忽略大小写 问题: 只能得到关键词的位置,不能得到关键词的内容 解决: match |
3. match:1). 查找一个关键词的内容和位置: var arr=str.match(/正则/i); 在str中查找符合"正则"要求的敏感词的内容和位置 返回值: 数组arr:[ "0":"关键词", "index": 下标i ] 若是找不到: 返回null 问题: 只能查找第一个关键词,不能查找更多关键词 2). 查找全部关键词的内容: var arr=str.match(/正则/ig) //g global 全局/所有 返回值: 保存多个关键词内容的数组 问题: 只能找到内容,没法得到位置 |
4. 即得到每一个关键词的内容,又得到每一个关键词的位置reg.exec() |
5. 替换: 将找到的关键词替换为指定的新值2种方式: 1). 简单替换: 将全部关键词替换为统一的新值 str=str.replace(/正则/ig,"新值") 查找str中全部符合“正则”要求的关键词,都替换为统一的新值。 问题: 全部字符串API都无权修改原字符串,只能返回新字符串。 解决: 若是但愿替换原字符串,就必须本身手动赋值回原变量中 衍生操做: 删除关键字: 其实将关键词替换为"" 2). 高级替换: 根据每次找到的关键词不一样,动态选择要替换的新值 str=str.replace(/正则/ig, function(kword){ 根据kword的不一样,动态生成新值 return 新值 }) 查找str中全部符合“正则”要求的关键词 每找到一个关键词,就自动调用一次回调函数 每次调用回调函数时自动传入本次找到的关键词给kword 回调函数中根据每次收到kword的不一样,动态返回新值给replace函数 replace函数自动将回调函数返回的新值,替换到字符串原关键词位置。 |
6. 切割: 将一个字符串,按指定的切割符,切割成多段子字符串2种: 1). 简单切割: 切割符是固定的 var arr=str.split("切割符") 将str按指定的"切割符",切割为多段子字符串,保存在数组arr中 固定套路: 打散字符串为字符数组 var chars=str.split("") 2). 复杂切割: 切割符不是固定的 var arr=str.split(/正则/i) |
三. RegExp对象: |
1.什么是:保存一条正则表达式,并提供了用正则表达式执行验证和查找的API 的对象 2.什么时候使用:只要在程序中保存和使用正则表达式,都要用RegExp对象 3. 如何使用:建立: 1). 用/建立(直接量): var reg=/正则/ig 什么时候: 若是正则表达式是固定不变的 2). 用new建立: var reg=new RegExp("正则","ig") 什么时候: 若是正则表达式须要在运行时才动态生成时
|
4.API:1). 验证: var bool=reg.test(str) 用正则reg,检测str是否符合正则的格式要求 问题: 正则默认只要找到部份内容与正则匹配就返回true 解决: 必须从头至尾完整匹配,才返回true 只要验证,必须前加^后加$,表示从头至尾的意思 2). 查找: 获取每一个关键词的内容和位置: var arr=reg.exec(str) 在str中查找下一个符合reg要求的关键词的内容和位置 若是反复调用reg.exec(),则自动会向后找下一个。 找不到时返回null 返回值: arr:[ "0":"关键词", "index": 关键词位置 ]
总结: a).验证只能用test d).既找内容有找位置用match e).找全部关键词内容和位置用exec |
1.什么是函数 |
什么是函数: 封装一项任务的步骤清单代码段的对象,再起一个名字。 为何: 重用! 什么时候: 只要一段代码可能被反复使用,都要建立函数。 |
2.如何使用 |
1).建立函数: JavaScript中建立函数的三种方式 a).使用function关键字声明方式建立命名函数
b).使用直接量赋值方式建立命名函数 var 函数名=function(形参1,形参2,...){ 函数体; return 返回值; } c).使用Function构造方法建立函数 |
3.重载(overload) |
1). 什么是: 相同函数名,不一样形参列表的多个函数,在调用时,可自动根据传入实参的不一样,选择对应的函数调用
2).为何: 减小函数名的数量,减轻维护的负担 3).什么时候用: 一件事,可能根据传入的参数不一样,执行不一样的操做时 4).如何: 问题: js语法默认不支持重载 由于js不容许多个同名函数同时存在 若是存在,最后一个函数会覆盖以前全部 解决: 使用arguments对象变通实现 什么是arguments对象: 每一个函数内自动建立的,准备接受全部传入函数的实参的 类数组对象 自动建立: 不用本身建立,就可直接使用 接受全部实参: 类数组对象: 长的像数组的对象 vs 数组: 相同: 1. 下标 2. length 3. 遍历 不一样: 类型不一样,API不通用 什么时候: 只要不肯定未来传入函数的参数个数时,就不定义形参列表,而是用arguments接住全部的实参值。
|
4.匿名函数: |
什么是: 定义函数时,不写名的函数 什么时候: 若是一个函数只用一次,不会反复使用,就不起函数名 为何: 节约内存!——使用一次后,自动释放! 如何: 2种场景: a). 回调函数: 本身定义的函数,本身不调用,而是传给其它对象或函数,被别人调用。 arr.sort(function(a,b){return a-b}) xhr.onreadystatechange=function(){ ... } pool.query(sql,[参数],function(err,result){ ... }) b). 匿名函数自调: 定义函数后,马上本身调用本身 为何: 避免使用全局变量,形成全局污染 什么时候: 全部js代码都应该封装在一个匿名函数自调中 如何: (function(){ ... })()//调用后,匿名函数内的局部变量都释放了 |
5. Function做用域和做用域链 |
6.闭包闭包就是可以读取其余函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,因此闭包能够理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部链接起来的桥梁 |
四. OOP |
1.什么是对象:程序中,描述现实中一个具体事物的程序结构 为何: 便于维护 2.什么是面向对象:程序中,都是先将多个事物的属性和功能,封装为多个对象,再按需调用对象的成员 什么时候: 从此,几乎全部程序,都用面向对象方式实现的 如何使用: 封装,继承,多态——三大特色 3.面向对象三大特色:封装:建立一个对象,集中保存一个具体事物的属性和功能 为何: 便于大量数据维护 什么时候: 只要使用面向对象编程,都要先封装对象,再按需使用对象的成员 如何: 3种: 1). 用{}: var obj={ 属性名: 值, ... : ... , 方法: function(){ ... this.属性名... }, ... : ... } 访问对象的成员: =属性+方法 属性其实就是保存在对象中的变量 对象.属性 方法其实就是保存在对象中的函数 对象.方法() this: 什么是: 在函数调用时,自动指向 . 前的对象的关键词 为何用: 避免在对象的方法中写死对象名,造成紧耦合。 什么时候用: 只要对象本身的方法,想访问本身的成员时,都要加this. 强调: 笔试时: a). this和定义在哪儿无关,只和调用时.前的对象有关 b). 全局函数调用没有 . , this默认指window 2). 用new建立: 2步: var obj=new Object(); obj.属性名=值; ... = ...; obj.方法名=function(){ ... this.属性名 ...} 揭示: js中一切对象底层,都是关联数组 *). 访问不存在的成员,不报错,返回undefined *). 强行给不存在的成员赋值,不报错,而是强行赋值新成员 *). 一样可用for in循环遍历一个对象中的全部成员 *). 访问下标: 2种: 1. obj["下标"] 若是属性名须要动态得到 2. obj.下标 若是属性名是写死的 问题: 一次只能建立一个对象,若是反复建立多个相同结构的对象时,代码会很冗余 解决: 用构造函数建立对象: 3). 用构造函数反复建立多个相同结构的对象: 什么是构造函数: 描述同一类型全部对象的统一结构的函数 什么时候: 反复建立多个相同结构的对象 如何: 定义构造函数: function 类型名(形参1,形参2,...){ this.属性名=形参1; this. ... =形参2; this.方法名=function(){ ... this.属性名 ...} } 反复调用构造函数,建立多个相同类型的对象 var lilei=new 类型名(实参,...); new 4件事: *). 建立一个新的空对象: {} *). 让新对象自动继承构造函数的原型对象: 新对象._ _proto_ _=构造函数.prototype *). 用新对象调用构造函数: 自动将构造函数中的this->new 经过强行赋值新属性的方式,自动添加规定的属性到新对象中,并将参数值,保存到新对象的对应属性中 *). 返回新对象的地址给变量 构造函数优势: 重用结构 缺点: 没法节约内存!
继承: 什么是: 父对象的成员,子对象无需重复建立就可直接使用 为何: 重用代码,节约内存 什么时候: 只要在多个子对象中包含部分相同的成员时 如何: /****** 必须知道的原理 *******/ js中的继承都是继承原型对象(prototype) 什么是原型对象: 集中保存全部子对象共有成员的父对象 建立原型对象: 买一赠一 每建立一个构造函数,就附赠一个空的原型对象 构造函数.prototype 什么时候继承: new的第2步: 让新对象自动继承构造函数的原型对象: 新对象._ _proto_ _=构造函数.prototype 继承里的自有属性和共有属性: 自有属性: 保存在当前对象本地,仅归当前对象自有的属性 共有属性: 保存在原型对象中,归多个子对象共有的属性 取值/访问时: 对象.成员名 修改时: 修改自有属性: 子对象.属性=值 修改共有属性: 原型对象.共有属性=值 若是强行用子对象.共有属性=值 后果: 为子对象本身添加一个同名的自有属性,今后子对象与父对象再无关系。——错误! 内置对象的原型对象: 内置对象: ES标准中规定的,浏览器已经实现了的,我们能够直接使用的对象 js内置对象: 11个: String Number Boolean Array Date RegExp Math Error Function Object global 其实,每种内置对象(除Math和global外)都是一种类型: 都由两部分组成: 1. 构造函数: 建立该类型的子对象 2. 原型对象: 保存该类型共有的函数 原型链: 什么是: 多级原型对象逐级引用造成的链式结构 做用: *. 保存了一个对象可用的全部成员 *. 控制着成员的使用顺序: 先自有,再共有 多态: 什么是: 一个函数在不一样状况下表现出不一样的状态 2种: *. 重载: *. 重写(override): 子对象中定义了和父对象中同名的成员 什么时候: 只要子对象以为父对象的成员很差用,就要定义自有的,来屏蔽父对象的。 4.自定义继承
5.静态静态(static)方法: 先了解什么是实例(instance)方法: 必须先有一个实例对象,才能调用的方法 好比: var arr=[1,2,3]; arr.sort() var str="Hello"; str.toUpperCase() 限制: 只有当前类型的子对象,才能使用的方法 什么是静态方法: 不须要任何实例,就可用类型名直接调用的方法(不是用具体的对象object调而是用·前的类型名) 好比: Object.setPrototypeOf() 什么时候使用: 2种: 1. 不肯定使用该方法的对象的类型时 2. 调用函数时,暂时没法肯定要使用该函数的对象是什么 如何定义: 定义实例方法: 将方法添加到原型对象中 定义静态方法: 将方法添加到构造函数对象上 构造函数.静态方法=function(){ ... } |
五. ES5: |
1. 严格模式:什么是: 比普通js运行要求更严格的模式 为何: js语言自己有不少广受诟病的缺陷 什么时候: 从此全部js代码都要运行在严格模式下 如何: 在当前做用域的顶部: "use strict";
要求: *). 禁止给未声明的变量赋值: *). 静默失败升级为错误: 静默失败: 执行不成功,也不报错! 2). 禁用了arguments.callee arguments.callee: 在调用函数时,自动得到当前正在执行的函数自己(实际上是ES5禁用递归)。 什么时候: 专门用于在递归算法中,代替写死的函数名 递归的问题: 效率极低!是由于重复计算量太大! 解决: 几乎全部的递归均可以用循环代替 3). 普通函数调用和匿名函数自调中的this再也不指向window,而是undefinde 2.保护对象:为何: js中的对象毫无自我保护能力 什么时候: 若是不但愿别人擅自修改对象的属性和结构时 1).如何: 保护属性: 将全部属性划分为2大类: 命名属性: 可用 . 访问到的属性 又分为2类: 数据属性: 直接存储属性值的属性 访问器属性: 不实际存储属性值,仅负责提供对另外一个数据属性的保护。 内部属性: 不能用 . 访问到的属性
数据属性: ES5规定,每一个数据属性,实际上是一个缩微的小对象 每一个属性对象其实包含四个特性: { value: 实际存储属性值, writable: 控制是否可修改, enumerable: 控制是否可被for in遍历,但用.依然能够访问 configurable: 控制是否可删除该属性 控制是否可修改其它两个特性 默认: 三个开关都是true 获取一个属性的四大特性: var attrs=Object.getOwnPropertyDescriptor(obj,"属性名") 得到obj对象的指定"属性"的四大特性 打开和关闭开关: Object.defineProperty(obj,"属性名",{ 从新定义obj的指定"属性"的开关 开关: true/false, ... : ... }) 问题: 一次只能修改一个属性的四大特性 解决: Object.defineProperties(obj,{ 属性:{ 开关:true/false, ... : ... }, 属性:{ ... ... } }) 问题: 没法使用自定义规则保护属性 解决: 访问器属性: 什么时候: 只要使用自定义规则保护一个数据属性时 如何: 前提: 必须先有一个隐藏的数据属性,实际存储属性值 定义访问器属性: 使用访问器属性: 完善以上俩个构造函数的综合
2).保护结构: 禁止添加/删除对象中的属性 3个级别: *). 防扩展: 禁止添加新属性 Object.preventExtensions(obj) 禁止给obj对象添加任何新属性 再试图添加,就会出现错误 原理: 每一个对象中都有一个内部属性: extensible:true preventExtensions()将对象的extensible:false *). 密封: 在兼具防扩展同时,再禁止删除现有属性 Object.seal(obj) 禁止向obj中添加新属性 禁止删除obj中现有属性 原理: 将extensible:false 同时还将每一个属性的configurable:false *). 冻结: 在兼具密封的基础上,同时禁止修改全部属性值 Object.freeze(obj) 禁止向obj中添加新属性 禁止删除obj中现有属性 禁止修改任何属性的值 原理: 自动将每一个属性的writable改成false 通常用于冻结公共属性 3.call/apply/bind()替换this: 1). 临时调用一次函数,并临时替换一次this: call: 传入函数的每一个实参必须做为一个单独的参数传入 apply: 传入函数的每一个实参必须放在一个数组中总体传入(apply的比call多一个功能就是打散数组,但结果和call是同样的) 什么时候: 若是全部实参是放在一个数组中给你的 2). 不调用函数,而是建立一个原函数的副本,副本永久绑定this和部分参数值: bind 什么时候使用: 修改回调函数的this时只能用bind 4.数组API:1). 查找: indexOf: 同String中的indexOf 什么时候使用: 在数组中查找一个指定元素的位置时 2). 判断: 判断数组中的元素是否符合要求 *). 判断数组中的元素是否都符合要求 var bool=arr.every(function(elem, i, arr){ return 判断结果 }) every会自动拿着回调函数在每一个元素上执行一次: 参数: elem自动获得当前元素值 i 自动获得当前位置 arr 自动获得当前数组对象 返回值: 利用得到的参数,判断当前元素是否符合要求,并返回判断结果。 只有回调函数在每一个元素上执行都返回true时,才总体返回true。只要碰到一个false,就返回false *). 判断数组中是否包含符合要求的元素 var bool=arr.some(function(elem, i, arr){ return 判断条件 }) some和every不一样的地方是只要包含一个知足条件的整个some就返回true
3). 遍历API: 对数组中每一个元素执行相同的操做 *). 遍历原数组中每一个元素,执行相同的操做: arr.forEach(function(elem, i, arr){ 对原数组中的元素值,执行操做 }) *). 依次取出原数组中每一个元素,执行相同的操做后,放入新数组中返回: var newArr=arr.map(function(elem,i,arr){ return 新值 }) 4). 过滤和汇总: 过滤: 复制出数组中符合条件的元素,组成新数组返回 var subArr=arr.filter(function(elem,i,arr){ return 判断条件 }) 汇总: 对数组中每一个元素的值进行统计,得出一个汇总的结果。 var result=arr.reduce( function(prev,elem,i,arr){ //prev: 得到截止目前的临时汇总值 return prev+elem }, base//起始时的基数 ) |
六.ES6: |
ES6:不改变原理的基础上,让API变的更简化 1. let: 代替var用于声明变量1). var的缺点: *). 声明提早: *). 没有块级做用域: 2).let的优势: *). 阻止了声明提早 *). 让let所在的块({...})也变为一级做用域 2.参数加强:1). 默认值: ES6中能够给形参提早设置一个默认值,调用时,若是没有给实参,就自动启用默认值代替。 如何: function fun(形参1, 形参2,..., 形参n=默认值){} 强调: 带默认值的形参必须出如今参数列表的末尾 2). 剩余参数: 代替arguments: arguments的问题: *). 不是纯正的数组类型,而是类数组对象,致使数组的全部API,arguments不能使用 *). 只能接住全部参数,不能有选择的接住部分参数 如何使用剩余参数: function fun(形参1, 形参2,...数组名){ //数组中就接住了除形参1,形参2之外的剩余的实参 //且"数组"是纯正的数组类型,可使用全部数组家的API } *注意:...三个点是语法,做用是收集 剩余参数的优势: *). 是纯正的数组,可以使用全部数组家API 3). 散播(spread): 代替apply,用于专门打散数组类型参数为单个值 apply的问题: 其实apply的主要功能是替换this,顺便打散数组类型参数 什么时候: 只要单纯但愿打散数组类型参数为单个值时 如何: 调用时: fun(...数组名) 先把数组打散后,再分别传给fun 至关于: fun(数组[0],数组[1],数组[2],...) *注意:...三个点是语法,做用是打散 3. 箭头函数: 简写一切匿名函数1).简化 *). 去function变=> *). 若是只有一个参数,可省略() *). 若是函数体只有一句话,可省略{} 若是仅有的一句话是return... ,则必须省略return 特性: 内外this通用! 若是和this无关时,或但愿内外this通用时,可改箭头函数 若是不但愿内外this通用时,就不能用箭头函数 4.解构: 提取出一个大的对象中的部分红员,单独使用。1). 数组解构: 下标对下标: var arr=[elem1, elem2,...]; || || var [变量1,变量2,...]=arr; 变量1=elem1 变量2=elem2 2). 对象解构: 属性对属性 var obj={属性1:值1, 属性2:值2, ... } || || var {属性1: 变量1, 属性2:变量2, ... }=obj 变量1=值1; 变量2=值2; 3). 参数解构: 实际上是对象解构在函数传参时的应用 什么时候用: 多个形参都不肯定是否有值时 如何: *). 定义函数时: 将全部形参都定义在对象结构中 function fun({ url:url, type:type, data:data, dataType:dataType }){ } 可简写为: function fun({url, type, data, dataType}){ *). 调用时: 全部实参都要放在一个对象结构中总体传入 fun({ url:"http://localhost:3000/index", type:"get", //data:, dataType:"json" }) 结果: 形参url ="http://localhost:3000/index 形参type="get" 形参data=undefined 形参dataType="json"
优势: *). 与参数个数无关 *). 与参数顺序无关
5.for of: 遍历索引数组1). for: for(var i=0;i<arr.length;i++){ arr[i] //当前元素 } 2). forEach: arr.forEach( (elem,i,arr)=>{ elem //当前元素值 }) 不灵活: *). 不能控制顺序 *). 不能控制步调 3). for of for(var elem of arr){ elem //当前元素值 } 不灵活: 只能得到元素值,不能得到元素位置 vs for in: for of: 可遍历数字下标的索引数组或类数组对象 for in: 只能遍历非数字下标的关联数组或对象(for in 不建议遍历索引数组,有风险,由于in不止遍历下标包括非数字的下标所有遍历,对于混搭的数组来讲有风险) 6.class: 对整个面向对象的简化:1).简化 *). 对单个对象直接量的简化: var obj={ 属性1: 值1, 属性2 : 变量, //若是属性名恰好和变量名相同,则只写一个 方法名:function(){//全部方法,再也不须要:function ... ... } } *). 对一种类型定义的简化: class *). 用class{}包裹构造函数和原型对象方法 *). 将构造函数名提高为类型名,构造函数统一改名为constructor *). 全部原型对象方法不用再添加到Prototype中,而是直接写在class内,与构造函数平级(不要逗号) class Plane { constructor (fname,speed,score){ this.fname=fname; this.speed=speed; this.score=score; } fly(){ ... } getScore(){ ... } } 2). 继承: *). 让子类型继承父类型: class Child extends Father{ extends代替了Object.setPrototypeOf(...) *). 子类型构造函数中必须先借用父类型构造函数: class Child extends Father{ constructor(...){ super(参数,...)//借父类型的构造函数 this.xxx=xxx; } } super代替了Father.call(this,...) super中不要加this! 3).封装 *).访问器属性: class 类名{ constructor(..., age){ ... ... 半隐藏的_age属性 this.age=age; } get age(){ return this._age;} set age(value){验证value并赋值} } *). 静态方法: class 类名{ constructor(){ } //必须使用当前类型的子对象才能调用的方法,称为实例方法。 实例方法(){ ... } //不须要使用当前类型的子对象,就可用类型名直接调用的方法 static 静态方法(){ ... } } 调用时: //静态方法不须要提早建立任何该类型的子对象,就可用类型名直接调用 类型名.静态方法() var obj=new 类型名() //实例方法要求必须先建立该类型的子对象,才可用子对象调用实例方法。 obj.实例方法() 7.promise1).什么时候:多个异步方法,要求必须顺序执行时。 2).为何:为了解决回调地狱问题 回调地狱:由于回调函数的嵌套层级太深致使的代码可读性差。 形成根源:异步函数的下一项任务,只能在函数调用初期就提早传入函数
3). 如何实现promise
须要修改的几个地方 Object.create()什么是: 建立一个新对象,让新对象继承指定的父对象 什么时候: 在没有构造函数的状况下,也想建立子对象继承父对象时 如何: var child=Object.create(father,{ 自有属性:{ value:值, 三个开关... } }) |