正则表达式
正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式检查字符串是否符合规则,提取符合规则的字符串
语法:var 变量 = new RegExp("正则表达式","匹配模式");
匹配模式:i 忽略大小写; g 全局匹配模式
var reg = new RegExp("a");//检查字符串是否含有a
var str = "bajjs"
// test()用来检查字符串是否符合正则表达式规则
var result = reg.test(str);
// true
//只要含有a都返回true
字面量创建正则表达式
语法 : 变量 = /正则表达式/匹配模式
reg = /a/i;
reg = /a|b/;//a或b
reg = /[ab]/;// a或b
reg = /a-z/;//a到z的任意小写字母
// 相同元素可以合并
reg = /a[bde]c/;// abc或adc或aec
// /[^ ]/除了
reg = /[^ab]/;// 除了a和b都是true
字符串和正则相关方法
stringObject.search(regexp)
//该参数可以是需要在 stringObject 中检索的子串,也可以是需要检索的 RegExp 对象
//返回值
//stringObject 中第一个与 regexp 相匹配的子串的起始位置。
//注释:如果没有找到任何匹配的子串,则返回 -1
/*search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置*/
stringObject.match(searchvalue)//searchvalue 必需。规定要检索的字符串值
stringObject.match(regexp)//必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象
stringObject.replace(regexp/substr,replacement)
/*regexp/substr 必需。规定子字符串或要替换的模式的 RegExp 对象。请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。
replacement 必需。一个字符串值。规定了替换文本或生成替换文本的函数*/
/*返回值
一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的*/
stringObject.split(separator,howmany)
/*separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度*/
/*返回值
一个字符串数组。该数组是通过在 separator 指定的边界处将字符串 stringObject 分割成子串创建的。返回的数组中的字串不包括 separator 自身。
但是,如果 separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本*/
量词
通过量词可以设置一个内容出现的次数
(量词只对它前面的一个内容起作用)
{n}正好出现n次
{m,n}出现n-m次
{m,}出现m次及以上
+至少一个,相当于{1,}
*0个或多个,相当于{0,}
?0个或1个,相当于{0,1}
^表示开头
&表示结尾
如果在正则表达式中同时使用^ &,则必须要求字符串完全符合正则表达式
.表示任意字符
在正则表达式中使用\作为转义字符
\.表示.
\\表示\
//去除开头的空格
str = str.replace(/\s/g , "");
//去除结尾的空格
str = str.replace( /^\s* / ,"");
//匹配开头和结尾的空格
str = str.replace( /\s*$/ ,"");
/^\s*|\s*$/g
ES6定义变量
let变量声明
// 1.必须先定义在使用
let a=100
console.log(a)
// 2.可以辨析变量重名问题
let name = "candy"
let name = "judy"
//报错,let声明的变量不能重名
var name = "sss"
var name = "zzz"
//相当于赋值
// 3.块级作用域
// 只会在{}内部起作用
var arr = [1,2,3,4,5,6,7]
for (let i = 0; i < arr.length; i++) {
var index = i
btn.onclick = function (){
console.log(index)
}
}//打印对应点击的数字1/2/3/4/5/6/7,let声明的变量每一次循环都会重新声明一个i
for (var i = 0; i < arr.length; i++) {
var index = i
btn.onclick = function (){
console.log(index)
}
}//直接打印最后一个7,因为for循环会先执行完成,当你点击的时候i已经变成了7
const 声明常量
const obj = {name:"popo"}
//用const声明一个对象由于对象是存储在堆和栈内存两个地方
obj = {name:"keke"}//const声明的常量不可改变,报错
obj.name = "keke"//只是将堆内存中的内容改变,地址没有改变,不会报错
箭头函数
// 1.形参只有1个的时候()可以省略,
var test = a => {
}
var test = (a,b) => {
}
// 2.只有返回值/只有一句话的时候可以省略{}
var test =() =>({name:"key"})//返回对象省略外部{}但是要加一个()防止解析错误
// 3.没有argument
// arguments函数立即建立的变量,能在函数没有形参的时候自动拿到调用函数的所有实参
var test = () => {
console.log(arguments)
}
test(1,2,3)
//返回伪数组1,2,3
解构赋值
var arr = [1,2,3]
arr[arr.length-1]//直接得到第三个数
let [x,y,z] = arr
//要想得到第3个数必须要有前两个数
// 交换数字(此时不能用let)
var a=5
var b=8
var [b,a] = [a,b]
console.log(a,b)
//a=8 b=5
// 多维数组
var arr=[1,2,[3,4,[5]]]
var [q,w[e,r,[t]]]=arr
console.log(t)//直接一一对应,返回5
// 对象的解构
var obj = {
name:"keke",
age:18,
position:"anhui"
}
//直接获取
console.log(obj.name,obj.age,obj.position)
//通过解构的方式获取
let {name,age,position}=obj
console.log(name,age,position)
// 如果有重名现象
let {name,age,position:mypositon}=obj
console.log(myposition)
argument伪数组
- arguments是一个类数组对象,他可以通过索引来操作数据,也可以获取长度
- 在调用函数时,我们所传递的实参会保存在arguments中,即使不定义形参也可以操作实参
- arguments.length可以用来获取实参的长度
- arguments中有callee属性,对应当前正在执行的函数对象
function fun(){
console.log(arguments.length);
}
fun("hi","tutu",true);
//3
// 取出
function fun(){
console.log(arguments[0]);
}
fun("hi","tutu",true);
// hi
// arguments中有callee属性,对应当前正在执行的函数对象
console.log(arguments.callee);
ES6展开运算符
…arr 展开数组
var a = [1,2,3]
var b = [4,5,6]
var c = [a,b]//返回数组嵌套数组
var c= [...a,...b]//返回[1,2,3,4,5,6]
…参数-实参-形参
// ...arr相当将传入的实参一一展开
var test = (...arr) =>{
console.log(arr)
}
test(1,2,3,4,5)
//返回[1,2,3,4,5]
//1传给a,2传给b,345传给arr
var test = (a,b,...arr) =>{
console.log(arr)
}
test(1,2,3,4,5)
//返回[3,4,5]
…展开对象
var obj = {
name:"keke",
age:12
}
var obj2 = {
location:"lili"
}
var obj3 = {
...obj1,
...obj2
}
console.log(obj3)
// obj3 = {
// name:"keke",
// age:12,
// location:"lili"
// }
模板字符串
<script>
let name = 'ouou'
let oli = `<li>
${name}
</li>`
console.log(oli)
let arr = ['huxin','liaoyujie','gongyi']
let newlist = arr.map(function(item,index){
return `<li class="${index==0?'active':''}">${item}</li>`
})
// ${}括号内可以写三目表达式,也可以写函数或变量名
</script>
字符串扩展
// 判断字符串中是否存在指定字符
let myname='candy lady'
console.log(myname.includes('a',5))//从索引为5开始查找
console.log(myname.startsWith('k',2))//索引为2字符开始
console.log(myname.endsWith('n',3))//对于前三个来看是不是以n结尾
// repeat重复
console.log(myname.repeat(2))//candy ladycandy lady
console.log(myname.repeat(0))//返回空字符
// 数值扩展
// 1.支持二进制和八进制
let num1 =100
let num2 =0x100
let num3 =0b100
let num4 =0o100
// 2.isFinite判断是否有限,而且只对数值有效/isNaN对nan返回true,对其他数值一律返回false
let num5=isFinite(100)//ture
let num6=isFinite(100/0)//false
let num7=isFinite('100')//false
let num8=isFinite(Infinity)//false
let num9=isFinite(NaN)//true
let num10=isFinite('100')//false
let num11=isFinite(Infinity)//false
// 极小常量Number.EPSILON
function isEqual(a,b){
return Math.abs(a-b)<Number.EPSILON
}
console.log(isEqual(0.1+0.2,0.3))//true
console.log(0.1+0.2===0.3)//false
// Math.trunc
console.log(Math.trunc(1.8))//1
console.log(Math.trunc(1.2))//1
console.log(Math.trunc(-1.8))//-1
console.log(Math.trunc(-1.2))//-1
// Math.sign判断一个数到底是正数还是负数还是0,对于非数值,会先将其转换为数值
Math.sign(-100)//-1
Math.sign(100)//1
Math.sign(0)//+0
Math.sign(-0)//-0
Math.sign('kiki')//-1
数组扩展
<script>
let arr = [1,2,3]
let arr2 = [...arr]
console.log(arr,arr2)
let myarr = [1,2,3,4,5,6,7]
let [a,b,...c]=myarr
console.log(a,b,c)//1 2 [3, 4, 5, 6, 7]
// Array from将伪数组转化为数组
// Array of新建一个数组
// find findIndex()
let arr1 = [11,22,33,44,55]
let res=arr1.findLastIndex(function(item){
return item>13
})
console.log(res)
// fill快速填充
let arr3=new Array(3).fill('lolo')
console.log(arr3)// ['lolo', 'lolo', 'lolo']
// flat() flatMap()扁平化处理 不会改变原数组
let arr4=[1,2,3,[1,2,3]]
let arr5=arr4.flat()
console.log(arr5)//[1, 2, 3, 1, 2, 3]
// 对于复杂类型
let arrs=[
{
name:'qq',
age:['dd','dds','ssf','ssc']
},
{
name:'ww',
age:['su','pp','qpqp','jiji']
}
]
let ress = arrs.flatMap(function(item){
return item.age
})
console.log(ress)//['dd', 'dds', 'ssf', 'ssc', 'su', 'pp', 'qpqp', 'jiji']
</script>
对象扩展
<script>
// 1.对象简写
let name='a'
let obj={
name,
test1(){
console.log("ddd")
}
}
// 2.对象属性
let gender='women'
let obj2={
[gender+'oo']:'kiki'
}
console.log(obj2);//{womenoo: 'kiki'}
// 3.扩展运算符
let obj3={
name:'gygy'
}
obj3.name='susu'
console.log(...obj,...obj3)//展开合并,一旦遇到相同属性,后面会把前面覆盖
// 4.Object.assign
console.log(Object.assign(obj,obj1,obj2,obj3))//将obj作为目标,obj1,2,3全部放入obj,相同属性覆盖
// Object.is 判断两者相等可以判断NaN
console.log(Object.is(parseInt('gugu'),NaN))
console.log(+0,-0)//false
</script>
函数扩展
// 1.参数默认值
function ajax(url,method='get',async=true) {
console.log(url,method,async)
}
ajax('/aaa','get',true)
// 2.rest参数 剩余参数
function test (x,y,...data){
console.log(data)
}
test(1,2,3,4,5,6)//[3,4,5,6]
// 3.name属性
console.log(test.name)//test
symbol()
<script>
// 给一个对象加属性的时候防止冲突
let s1=Symbol()
let s2=Symbol()
// 每次都生成一个不一样的symble类型数据
// 1.不能运算 2.显式调用tostring()3.隐式转换Boolean
let name=Symbol()
let age=Symbol()
let obj={
[name]:'kiki',
[age]:13
}
console.log(obj[name],obj[age])
</script>
ES6模块化语法
function A1(){
console.log("a1")
}
function A2(){
console.log("a2")
}function A3(){
console.log("a3")
}
// export 暴露/导出
export {
A1,
A2
}
//导出
<script type="js文件名">
import{A1,A2} from './文件地址 '
<script>
//重名问题
<script type="js文件名">
import{A1,A2 as A_A1} from './文件地址 '
<script>
工厂函数
工厂函数可以自己定义传入的值,每次调用函数可以获得不同的值;
工厂相当于可以大批次使用,方便而且可以用一个固定的模式,后面只需要调用的时候输入不同实参就可以了
function Fun (name,age){
var obj = new Object()
// var obj = {}
obj.name = name
obj.age = age
obj.inner = []
return obj
}
// 调用工厂函数
var obj1 = Fun("kiki",18)
console.log(obj1)
var obj2 = Fun("dudu",20)
console.log(obj2)
自定义函数
自定义函数可以自动创建和返回一个对象,也能达到工厂函数效果,而且更简洁
function Fun(name,age){//一般为首字母大写
// 不用再在内部创建obj对象
this.name=name//this指向实例化对象,而该对象赋值给obj1,所以相当于指向obj1
this.age=age
this.inner=[]
}
var obj1 =new Fun("kiki",18)//构造函数要有new关键词,new过程是实例化过程生成实例化对象
console.log(obj1)
console.log(obj1.name)
构造函数(多模块相似直接调用)
构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建对象设置为函数中的this,在构造函数中可以使用this来引用新建对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
<body>
<!--基本页面布局-->
<div class="box1">
<h1></h1>
<ul></ul>
</div>
<div class="box2">
<h1></h1>
<ul></ul>
</div>
<script>
// 面向对象
// 后端传入数据
var date = {
title:"ti",
list:["111","222","333"]
}
var date2 = {
title:"popo",
list:["121","122","833"]
}
// 构造的函数不需要再变化,只需要改变传入的实参就可以,从相当于利用函数将页面排版,然后再将不同内容以参数形式传入
// 构造函数
function Fun(select,obj){
this.ele = document.querySelector(select)
this.title = obj.title
this.list = obj.list
this.render = function (){
//渲染页面
//获取div中的h1和ul标签
var h1 = this.ele.querySelector("h1")
var ul = this.ele.querySelector("ul")
// 将后端传入的内容放到h1和ul标签中
h1.innerHTML = this.title
ul.innerHTML = this.list.map(item=>`<li>${item}</li>`).join("")
}
}
//得到后端传入的函数
var obj1 = new Fun(".box1",date)
obj1.render()
var obj2 = new Fun(".box2",date2)
obj2.render()
</script>
</body>
原型对象
• 当我们访问对象的一个属性或方法时,他会先在对象自身中寻找,如果有则直接使用,没有则去原型对象中寻找,;
• 在创建构造函数时,可以将这些对象共有的属性和方法统一添加到构造函数的原型对象中,这样不同分别为每一个对象添加,也不会影响到全局作用域就可以使得每个对象都具有这些属性和方法
• 向原型对象中添加方法:属性名.prototype.方法
• 原型对象也是对象,也有原型,但至多两层,到达object的原型没有原型则返回null
对象.__proto__
===构造函数.prototype
// 原型对象:共用内存
//只要原型中有这个函数,这个原型中的属性和函数在原先的这个函数中也会有
Fun.prototype.render(){
//渲染页面
//获取div中的h1和ul标签
var h1 = this.ele.querySelector("h1")
var ul = this.ele.querySelector("ul")
// 将后端传入的内容放到h1和ul标签中
h1.innerHTML = this.title
ul.innerHTML = this.list.map(item=>`<li>${item}</li>`).join("")
}
类ES6-class
<script>
function CreatObj(){
this.name = name
}
CreatObj.prototype.say = function (){
console.log("hello")
}
// 类--实现简写
class CreatObj {
//构造器函数
//constructor内做属性的挂载
constructor(name) {
this.name = name
}
// 方法放在类内部还是共享内存的
say(){
console.log("hello")
}
}
var obj = new CreatObj("kiki")
console.log(obj)
obj.say()
</script>
面向对象继承
Person.prototype.say=function (){
console.log(this.name,"hello")
}
Person("kiki",18)
var obj2 = {
grade:100
}
Person.call(obj2,"kiki",12)
//返回100,kiki,12
console.log(obj2)
``
// 非继承写法
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.say=function (){
console.log(this.name,"hello")
}
Person("kiki",18)
function Student(name,age,grade){
this.name = name
this.age = age
}
Student.prototype.say = function (){
console.log(this.name,"hello")
}
Student("lili",19)
// 继承写法
function Student(name,age,grade){
Person.call(this,name,age)
this.grade = grade
}
var obj = new Student("kiki",18,100)
console.log(obj)
原型继承
// 原型继承
Student.prototype=Person.prototype//缺点:两者就完全相同了
Student.prototype=new Person()
// 基础增加方法
Student.prototype.print=function (){
console.log(this.name,this.grade)
}
//基础覆盖
Student.prototype.say=function (){
console.log(this.name,this.grade)
console.log(this.name,"hello")
}
// 增强原来的方法
Student.prototype.say2=function (){
this.say()
console.log(this.name,"okok")
}
ajax
//创建
const xhr = new XMLHttpRequest()
//请求
xhr.open('请求⽅式', '请求地址', 是否异步)
// 使⽤ xhr 对象中的 send ⽅法来发送请求
xhr.send()
//接受
xhr.onreadyStateChange =function(){
if(xrh.readyState==4&&xhr.status==200){}
}
Ajax状态码
readyState === 0 : 表示未初始化完成,也就是 open 方法还没有执行
readyState === 1 : 表示配置信息已经完成,也就是执行完 open 之后
readyState === 2 : 表示 send 方法已经执行完成
readyState === 3 : 表示正在解析响应内容
readyState === 4 : 表示响应内容已经解析完毕,可以在客户端使用了
get/post请求
const xhr = new XMLHttpRequest()
// 直接在地址后面加一个 ?,然后以 key=value 的形式传递 // 两个数据之间以 & 分割
xhr.open('get', './data.php?a=100&b=200')
const xhr = new XMLHttpRequest() xhr.open('post', './data.php')
type
代表 请求方式
url
代表 请求url路径
data
代表 发送数据
success
代表 下载数据成功以后执行的函数
error
代表 下载数据失败以后执行的函数
promise
定义一个 Promise 对象,该对象有三个状态,pending (进行中)、resolved (成功)和 rejected (失败)
let pro = new Promise()
let pro = new Promise(function(resolve , reject){
//封装异步操作
setTimeout(() => {
//成功时
let data = '数据库中的用户数据'
//调用resolve
resolve(data)
//失败时
let err = '数据传输失败'
//调用reject
reject(err)
},1000)
})
调用 Promise 对象的 then 方法:
传入两个参数,
• 第一个是 Promise 对象 状态为 resolved 时的 回调函数
• 第二个是 Promise 对象 状态为 rejected 时的 回调函数
async和await
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值
await 也是一个修饰符,只能放在async定义的函数内
// 定义一个异步函数,3秒后才能获取到值
function getSomeThing(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('获取成功')
},3000)
})
}
async function test(){
let a = await getSomeThing();
console.log(a)
}
test(); // 3秒后输出:获取成功
fetch
fetch()使用 Promise,不使用回调函数fetch()使用 Promise,不使用回调函数
语法:
fetch(url)
.then(...)
.catch(...)
cookie
cookie的小量信息能帮助我们跟踪会话,一般该信息记录用户身份
//添加cookie
Cookie c = new Cookie("username","peter");
c.setMaxAge(24*60*60);
response.addCookie(c);
//删除cookie
Cookie cookie = new Cookie("username","peter");
cookie.setMaxAge(0);
response.addCookie(cookie);
//修改cookie
Cookie cookie = new Cookie("username","joker");
cookie.setMaxAge(24*60*60);
response.addCookie(cookie);
jsonp
Ajax
直接请求普通文件存在跨域无权限访问的问题,不管是静态页面、动态页面、web服务,只要是跨域请求,一律不准
jsonp
是一种跨域通信的手段,利用script标签的src属性来实现跨域,通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,只支持get方法
function jsonp(req){ var script = document.createElement('script'); var url = req.url + '?callback=' + req.callback.name; script.src = url; document.getElementsByTagName('head')[0].appendChild(script); }