JavaScript常见输出
window.alert() 弹出框警告
document.write() 将内容写到HTML文档中
innerHTML 写入到HTML元素中
console.log() 控制台输出
1 函数中的arguments使用
每个函数内部都有一个 arguments ,系统内置的。
arguments是用来储存实际传入的参数
//求传入任意数字的和?varsum=0;//求和的数functionsumFunction(){for(i=0;i<arguments.length;i++){//arguments.length代表当前输入已存储参数的个数。sum+=arguments[i];}returnsum;}alert(sumFunction(1,2,3,4,5,6));
2 函数的作用域
任何程序运行时候都要占用空间,函数调用的时候也要去占用空间
垃圾回收机制:调用完函数之后,系统会分配对应的空间给这个函数使用(空间大小一般由函数里声明的变量和形参决定),当函数使用完毕以后,这个内存会被释放,还给系统。
在函数内部声明的变量和形参是属于当前函数的内存空间。
内存管理机制:在函数中声明的变量和形参,会随着函数的调用被创建,随着函数的调用结束而销毁。在函数中声明的变量和形参,有效范围是当前函数(当前函数的大括号内),作用域,局部作用域。
vara=10,b=20;// 声明在全局的变量叫全局变量functionshow(a){varb=100;// 在函数内部声明,局部变量a+=5;alert(a+","+b);}
3 函数递归
满足以下三个特点就是递归:
函数自己调用自己
一般情况有参数
一般情况下有return
注:递归可以解决循环能做的所有事情,有一些循环不容易解决的事情,递归也能解决。
//计算1~n的和?//正常函数写法functionsum(n){varres=0;for(i=1;i<=n;i++){res+=i;}returnres;}alert(sum(100));//递归写法/* 方法:1.首先去找临界值,即无需计算,获得的值。
2.找这一次和上一次的关系。
3.假设当前函数已经可以使用,调用自身算上一次。
sum(100)== sum(99)+ 100;
sum(n)== sum (n-1)+n;
*/functionsum(n){if(n==1){return1;}returnsum(n-1)+n;}alert(sum(100));
4 函数闭包
满足以下特点的叫做闭包
函数嵌套函数
内部函数使用外部的形参和变量
被引用的形参和变量就不会被 【垃圾回收机制所回收,使内部函数的变量常驻内存中】
window.onload=function(){//闭包实现按钮遍历完后,点击按钮输出对应的键值。varoBtn=document.getElementsByTagName("button");for(vari=0;i<oBtn.length;i++){oBtn[i].onclick=(function(index){returnfunction(){alert(index);}})(i);//这里的i相当于传入函数的参数 所以就是index就是等于i }/* 上面的是简写成立即执行函数的闭包
for(var i = 0;i < oBtn.length;i++){
oBtn[i].onclick = btnClick(i);
}
//btnClick(0) index = 0
function btnClick(index){
return function(){
alert(index);
}
} */
5 数组方法
方法格式返回值说明
Math.random()var sum = Math.random() * 10数字随机数: 随机生成0 ~ 1之间的小数
push()数组.push(参数1,参数2,...)插完元素以后的数组的长度给数组的末尾添加元素
pop()数组.pop() 不用传参取下一个元素从数组末尾取下一个元素
shift()数组.shift() 不用传参取下的元素从数组头部取下一个元素
unshift()数组.unshift(参数1,参数2,...)插完元素以后的数组的长度给数组的头部插入元素
concat()数组.concat(数组,数据,...)合并成的新数组,原数组不会改变拷贝原数组,生成新数组
slice()数组.slice(start, end)生成新数组原数组不会发生改变可以基于当前数组获取指定区域元素 [start, end] 提取出元素生成新数组
splice()数组.slice(开始截取的下标, 截取的长度,插入数据1,插入数据2...)截取下来的元素组成的数组对元素进行增删改
join()数组.join(字符串)拼接好的字符串将数组中的元素,用传入的拼接符,拼接成一个字符串
reverse()数组.reverse()逆序后的数组,此方法会修改原数组数组逆序
sort()数组.sort()排序后的数组,此方法会修改原数组默认从小到大排序,按照字符串排序
6 ECMA5新增数组方法
方法格式参数返回值说明
indexOf()数组.indexOf(item,start)item 任意数据,start 小标,可以不传,默认为0-1 没有查到,>= 0 查到元素的下标在数组 中查找item元素下标
forEach()数组.forEach(item,index){函数}item遍历到的当前数组的内容,index遍历到的当前数组元素下标item与index数组遍历
map()数组.map(item, index, arr){函数}不会改变原数组,而是将里面函数执行一次返回新数组遍历当前数组,然后调用参数中的方法
filter()数组.filter((item, index,array) => {函数})运行定义的函数后,返回符合的数组数组过滤
som()数组.some((item,index,arr) => {函数})有返回true,没有返回false,只要找到符合条件的元素,后面的循环就停止了在数组中查找是否有符合内容的元素
every()数组.every((item,index,arr) => {函数})有返回true,没有返回false,只要找不到符合条件的元素,后面的循环就停止了在数组中查找是否有符合内容的元素
reduce()归并arr.reduce(prev, next, index, arr)prev第一次是 下标为0的元素,第二次开始 上次遍历retturn的值,next 从下标1开始,当前遍历到的元素,arr数组本身
// reduce()归并vararr=[34,65,33,87,24,56]varres=arr.reduce((prev,next,index,arr)=>{console.log(prev+","+next);returnprev+next})alert(res)
7 字符串方法
方法格式参数返回值说明
indexOf() 字符查找字符串.indexOf(text, start)text需要查找的字符串,start从哪里开始查找的下标-1说明没有找到查找text在字符串中的位置
lastIndexOf()字符串.lastIndexOf(text)text需要查找的字符串-1说明没有找到查找text在字符串最后一次出现的位置
search()字符串.search(text)text需要查找的字符串或者 正则表达式-1说明没有找到查找text在字符中第一次出现的位置
match()字符串.search(text)text需要查找的字符串或者 正则表达式null说明没有找到匹配返回字符串中的所有符合text规则的字符数组
substring()字符串.substring(start, end)start, end 开始位置与结束位置新的字符串将字符串中 [start, end] 提取,生成一个新的字符串
substr()字符串.substr(start, length)start开始位置,length要生成新字符串的长度新的字符串提取字符串
slicce()字符串.slicce(start, end)start, end 开始位置与结束位置,不包括第end位新的字符串提取start到end 的字符串
replace() 过滤替换supStr.replace(oldStr,newStr)oldStr旧字符串,newStr新字符串新的字符串用newStr将supStr中的oldStr替换掉,生成新的字符串
new RegExp('\','g')txtData.replace(newRegExp('\','g'), '/')替换字符串中所有匹配上的字符或则使用replaceAll()但是兼容性不高
split() 字符串分割字符串.split(分隔符,length)分隔符为字符串里面的字符,lenth控制返回数组元素格式,一般不用数组对数组会用分隔符进行分割,将分割后的子串,放到数组中
字符串大小写转换toLowerCase() 转换成大写toUpperCase() 转换成小写改变原字符串字符大小写转换
concat字符串拼接字符串.concat(字符串1,字符串2,...)字符新的字符串拼接字符串
fromCharCode()将ASCII编码转换成对应的字符。
8 正则表达式
/*
敏感词过滤
*/vararr=[/靠/ig,/tmd/ig,/nm/ig,/cao/ig];functionbtnClick(){varoTxt=document.getElementById("txt1");varoMsg=document.getElementById("msg");varoValue=oTxt.value;for(i=0;i<arr.length;i++){oValue=oValue.replace(arr[i],"*");}oMsg.innerHTML=oValue;oTxt.value='';}
9 对象方法
delete 关键字 删除对象属性或者方法
varobj={name:'zhangsan',age:23}deleteobj.ageconsole.log(sunStr);// {name:'zhangsan'}
Math 数学运算函数
方法说明
Math.random()返回0 ~ 1之间的随机小数(可能是 0,不可能是 1)
Math.max(num1, num2)返回较大的数
Math.min(num1, num2)返回较小的数
Math.abs(num)绝对值
Math.ceil(19.3)向上取整(20)
Math.floor(11.8)向下取整(11)
Math.pow(x, y)x的y次方
Math.sqrt(num)开平方
日期对象
// 获取当前时间vartimeDate=newDate()conlose.log(tiemDate)// 传入时间初始化vartimeDate=newDate("2000-01-01")vartimeDate=newDate("2000/01/01")// 传入参数顺序 年 月 日 时 分 秒 毫秒 vartimeDate=newDate(2000,0,1,8,30,50)// 可以直接传入某一时间距离1970年1月1日至今的毫秒数vartimeDate=newDate()conlose.log(tiemDate)
方法说明
set/getDate()从Date对象中返回一个月中的某一天
getDay()从Date对象返回一周中的某一天(0 ~ 6)
set/getMonth()从Date对象中返回月份(0 ~ 11)
set/ getFullYear()从Date对象中返回年份
set/getHours()返回Date对象中的小时(0 ~ 23)
set/getMinutes()返回Date对象中的分钟(0 ~ 59)
set/getSeconds()返回Date对象中的秒数(0 ~ 59)
set/getMilliseconds()返回Date对象的毫秒
set/getTime()返回1970年1月1日至今的毫秒数
getTimezoneOffset()返回本地时间与格林标准时间的分钟差
对象遍历方法
对象遍历 只能通过for ..in 方法
varperson={username:"zhangsan",age:18,sex:"男"}for(variinperson){document.write("对象遍历:"+i+","+person[i])}
10 setInterval定时器
格式:
vartimer=setInterval(函数,毫秒数)clearInterval(timer)// 取消定时器
功能:每隔对应毫秒数,执行一次传入的函数
11 Bom对象
系统对话框
方法参数返回值说明
alert()无无弹出警告窗
confirm()无确认返回true,取消 false带取消和确定的提示框
prompt()1.面板显示内容 2.输入框里面默认参数(可以不传)确认返回输入框内容,取消返回null带输入框的提示框
varres=prompt("请输入内容",100);conlose.log(res)
open() 打开新窗口
参数1参数2参数3
跳转的url 打开一个新窗口,加载url字符串,给打开的窗口起一个名字一串特殊含义的字符串
functionbtnClick(){open("http://www.baidu.com","xxx")}
History 历史记录
window.history 掌管的是,当前窗口(注意不是浏览器)历史记录(只要加载的url不一样就会产生历史记录)
history .length 输出当前窗口历史记录条数
history .back 返回上一条历史记录
history .forward() 前进到下一条历史记录
history .go() 参数 0 刷新当前页面 正整数 前进n条记录 负整数 后退n条记录
location页面跳转
方法说明
location.assign(url)在当前窗口跳转到url
location.replace(url)在当前窗口替换成新的url,不会产生历史记录
location.reload(url)刷新当前窗口
location.reload(true)不经过浏览器缓存强制从服务器加载
12 Dom操作
节点获取
方法返回值功能
document.getElementById(id)符合条件的一个节点通过id获取节点
node.getElementsByTagName(标签名)伪数组/l类数组从node节点,通过元素标签名获取元素节点
node.getElementsByClassName(class名)伪数组/l类数组通过class获取符合条件的元素节点
document.getElementsByName(name属性的值)节点通过name属性的值获取符合条件的元素节点
document.querSelector(css选择器)一个元素节点,找到符合条件的第一个元素节点传入的参数为css选择器
document.querySelectorAll(css选择器)一个伪数组
node.parentNodenode的父节点获取node节点的父节点
节点元素样式获取
方法说明
node.currentStyle['height'] IE方法或者 getComputedStyle(node).['height'] 谷歌方法node表示元素节点,[] 里面是获取的样式属性
node.getAttribute("class")获取node节点的class属性的值
node.setAttribute("class" , “box”)给node节点添加值为box的class属性
node.removeAttribute("title")删除node节点的tille属性
node.innerHTML = "..."插入的html标签会被解析
node.innerText= "..."插入纯文本,里面写入html便签也不会解析
node.outerHTML= "..."从外标签开始到外便签结束 会解析标签
访问子节点方法
方法说明
childNodes()访问当前节点下所有的子节点
firstChild()访问子节点中的首位
lastChild()访问子节点中的最后一位
nextSibling()访问当前节点兄弟节点中的下一个节点
previousSibling()访问当前节点兄弟节点的上一个节点
节点操作
方法返回值说明
document.createElement()新创建的标签创建一个新节点
node1.appendChild(node2)将node2 节点 插入到node1 节点的末尾
document.createTextNode(文本)新创建的文本标签穿件文本节点(纯文本)
box1.parentNode.insertBefore(box2, box1)将box2节点添加到box1的前面
box1.parentNode.replaceChild(box2, box1)
node.cloneNode()克隆出来的新节点克隆node节点本身和子节点
box.parentNode.removeChild(box)将box节点从页面上删除
ps:parentNode 表示的是此节点的上级父节点
元素宽高、边距获取
offsetWidth 元素宽度获取
offsetHeight 元素高度获取
offsetLeft 元素距离左侧距离获取
offsetTop 元素距离上面距离获取
varoDiv=document.getElemenByid("div1")alert(oDiv.offsetWidth)// width + border + padding (眼睛实际看到的宽度)
浏览器宽高获取
获取浏览器高度写法
varwindowHeight=document.documentElement.clientHeight||document.body.clientHeight
获取浏览器宽度写法
varwindowWidth=document.documentElement.clientWidth||document.body.clientWidth
13 事件与事件类型
鼠标事件
事件名称说明
click单机
dblclick双击
mouseover鼠标移入(会重复触发)
mouseout鼠标移出(会重复触发)
mousemove鼠标移动(会不停触发)
mousedown鼠标按下
mouseup鼠标抬起
mouseenter鼠标移入(不会重复触发)
mouseleave鼠标移出(不会重复触发)
键盘事件
事件名称说明
keydown键盘按下 (如果按下不放手会一直触发)
keyup键盘抬起
keypress键盘按下(只支持字符键)
window 事件
事件名称说明
load当页面加载完成以后触发
unload当页面解构的时候触发(刷新页面,关闭当前页面) IE浏览器兼容
scroll页面滚动事件
resize窗口大小发生变化时触发
表单事件
事件名称说明
blur失去焦点
focus获取焦点
select当我们在输入框内选中文本时候触发
change当我们对输入框的文本进行修改并且失去焦点的时候
submit当我们点击submit上的按钮才能触发
reset当我们点击reset上的按钮才能触发
14 事件对象获取
oBtn.onclick=function(ev){// 事件对象获取方式 固定写法vare=ev||window.eventalert(e)}
获取当前鼠标的位置
x坐标y坐标说明
clientXclientY原点位置:可视窗口的左上角
pageXpageY原点位置:整个页面的左上角(包含滚动出去的滚动距离)
screenXscreenY原点位置:电脑屏幕的左上角
document.onmousedown=function(ev){vare=ev||window.event;alert(e.clientX+","+e.clientY)alert(e.screenX+","+e.screenY)}
事件对象属性
shiftKey 按下shift键,为true,默认为false
altKey
ctrlkey
metaKey
window系统 按下window键为true
macos系统 按下command键为true
注:和其他的操作进行组合,形成一些快捷键的操作
document.onmousedown=function(ev){vare=ev||window.event;vararr=[]if(e.shiftKey){arr.push("shift")}if(e.altKey){arr.push("altKey")}if(e.ctrlKey){arr.push("ctrlKey")}}
键盘事件对象属性
keyCode 键码
which
返回值:键码返回的是大写字母的ASCII码值,不区分大小写
格式:var which = e.which || keyCode
注:只在keydown下支持
charCode 字符码
which
返回值:字符码区分大小写,当前按下键对应的ASCII码值
格式 : var which = e.which || charCode
注:只在keypress下支持
window.keypress=function(ev){vare=ev||window.eventvarwhich=e.which||e.charCodealert(which)// 可以通过判断 获取的到which 来 确认执行定义的函数}
Target目标触发
Target的指向就是触发当前事件的元素,this永远指向当前函数的主人。
varoUl=document.getElementById("ul1")oUl.onclick=function(ev){vare=ev||window.eventvartarget=e.target||window.event.srcElementalert(this.tagName)alert(target.innerHTML)}
阻止事件冒泡
有浏览器兼容问题
cancelBubble = true
stopPropagation()
varaDivs=document.getElementsByTagName("div")for(vari=0;i<aDivs.length;i++){aDivs[i].onclick=function(ev){vare=ev||window.eventalert(this.id)cancelBubble=true// 阻止冒泡stopPropagation()// 阻止冒泡}}
事件委托
实现步骤:
找到当前节点的父节点或则祖先节点
将事件添加到找到的这个父节点或则祖先节点上
找到触发对象,判断触发对象是否是想要的触发对象,进行后续操作
如下:li 委托 ul 将点击的li变成红色
varoUl=document.getElmentById("ul1")oUl.onclick=function(ev){vare=ev||window.eventvartarget=e.target||window.event.srcElementif(target=e.nodeName.toLowerCase()=="li"){target.style.backgroundColor='red'}}<ul id="ul1"><li></li><li></li><li></li></ul>
事件监听器
removeEventListener() 删除事件中的函数
格式:node.removeEventListener()
参数:
第一个参数:事件类型
第二个参数:删除函数的名称
addEventListener() 给元素的事件添加函数
格式: node.addEventListener("click")
参数:
第一个参数:事件类型
第二个参数:绑定函数
第三个参数:布尔值
true 事件捕获
false 事件冒泡 默认
15 localStorage 本地存储
只能存储String
localStorage 对象
localStorage .setItem(name,value); 写入
localStorage .getItem(name); 读取
localStorage .removeItem(name); 删除
16 强制改变this指向
call() 方法
格式:函数名.call()
参数:
第一个参数:传入该函数this指向的对象,传入什么强制指向什么
第二个参数:将原函数的参数往后顺延一位
apply() 方法
格式:函数名.apply()
参数:
第一个参数:传入该函数this指向的对象,传入什么强制
第二个参数:数组 数组放我们原有所有参数
bind() 方法
预设this指向
functionshow(x,y){alert(this)alert(x+","+y)}// call方法show.call("call",20,40)// apply 方法show.apply("apply",[20,40])// bind 方法show.bind("bind")(40,50)
17 ECMA6数组方法
Array.from()// 将伪数组转换成真数组
方法返回值说明
find((item,index,arr) => {函数})找到的元素在数组中查找符合条件的元素,只要找到一个符合的元素,就终止遍历
findIndex((item) => {函数})找到符合元素的下标
数组.copywithin(开始下标,start,end)[start,end] 范围数组内容覆盖
18 ECMA6对象合并
Object.assign 合并对象
将所有传入的对象,都合并到第一个对象中
varobj1={a:10}varobj2={b:20,c:30}varobj3={d:40,f:["hello","world",true]}Object.assign(obj1,obj2,obj3)
19 Map映射
会将重复的合并
// map 映射letmap=newMap()// 添加数据map.set("张三","打鱼的")map.set("李四","种地的")map.set("王五","挖煤的")map.set("李四","打猎的")// 取值alert(map.get("王五"))
20 ajax网络请求
oBtn.onclick=function(){//1、创建ajax对象varxhr=null;try{xhr=newXMLHttpRequest();}catch(error){xhr=newActiveXObject("Microsoft.XMLHTTP");}//2、调用open/*
第一个参数:请求方式 get post
第二个参数:url
第三个参数:是否异步
true 异步 false 同步
*/// get 请求直接在open方法总将数据在url中通过 ? 拼接提交xhr.open("get","1.get.php?username=yyy&age=21&password=dasdsd",true);/*
post 提交数据,需要通过send方法进行提交
*///3、调用sendxhr.send();//4、等待数据响应xhr.onreadystatechange=function(){if(xhr.readyState==4){//判断本次下载的状态码是多少if(xhr.status==200){alert(xhr.responseText);}else{alert("Error:"+xhr.status);}}}}
21 cookie本地存储
可以设置过期时间
最大存储4kb,每个域名下最多可以储存50条数据
只能存字符串
cookie语法:
格式:name=value;[expires=data];[path=path];[domain=somewhere.com];[secure]
name 键
value 值 都是自定义
注: 中括号参数属于可选参数,可以不添加
document.cookie='username=xxx'// 设置cookiealert(document.cookie)// 获取cookie
cookie编码中文
encodeURIComponent 将中文编译成对应的字符
decodeURIComponent 将对应的字符编译成中文
document.cookie='username=xxx'+encodeURIComponent("钢铁侠")// 设置cookiealert(decodeURIComponent(document.cookie))// 获取cookie
expires: cookie过期时间
必须填写,日期对象
系统会自动清除过期cookie
document.cookie=`username=xxx;expires=${时间对象}`
path:cookie限制访问路径
访问限制,如果不去设置,默认加载当前,html文件的路径
我们设置cookie路径,和当前文件的路径,必须保持一致,如果不一致,cookie访问失败
document.cookie="username=xxx;path="+"/code14/cookie/demo"
domain:cookie限制访问域名
如果不去设置,默认加载的是当前.html文件的服务器域名
如果加载当前文件域名和设置 的域名不一样,设置cookie失败
document.cookie="username=xxx;domain="+"localhosx"
Cookie的secure设置参数
如果不设置,设置cookie,可以通过http协议加载文件设置,也可以通过https协议加载cookie文件
设置这个字段之后,只能设置https协议加载cookie
22 构造函数封装
function Person(name,sex){// 这里this指向整个构造函数对象this.name = name this.sex = sex this.showName = function (){console.log('我的名字叫' + this.name);}this.showSex = function (){console.log('我的性别是' + this.sex);}}var p1= new Person('张三','男')p1.showName()p1.showSex()var p2= new Person('李四','男')p2.showName()p2.showSex()
23 Prototype 原型对象
概念:每一个函数上,都有一个原型对象Prototype
用在构造函数上,我们可以给构造函数的原型Prototype,添加方法
1、如果将方法添加到构造构造函数的Prototype原型对象上,构造函数构造出来的对象共享原型上的所有方法
vararr1=[10,23,244,34]vararr2=[23,435,45,546,546]Array.prototype.sum=function(){varres=0;for(vari=0;i<this.length;i++){res+=this[i]}returnres}console.log(arr1.sum());console.log(arr2.sum());console.log(arr1.sum==arr2.sum);// true
24 原型链继承
// Teddy.Prototype = Dog.Prototype() 非常错误的写法for(varfuncNameinDog.Prototype){Teddy.Prototype[funcName]=Dog.Prototype[funcName]}
25 __ proto __与instanceof 关键字
构造函数构造出来的对象,有一个属性__ proto ,指向构造出这个对象的构造函数的原型 ,每个对象的proto__属性指向自身构造函数的prototype;
instanceof 关键字
功能:判断某一个对象是否是这个构造函数构造出来
functionDog(obj){this.obj=obj}varxiaobai=newDog({name:'小白',type:'比熊',age:23})console.log(xiaobaiinstanceofDog);// trueconsole.log(xiaobaiinstanceofObject);// true
26 Promise构造函数(解决回调地狱)
//在EcmaScript 6 中新增了一个API Promise//Promise是一个构造函数varfs=require("fs")//创建Promise容器//1.给别人一个承诺 // Promise容易一旦创建,就开始开始执行里面的代码varp1=newPromise(function(resolve,reject){fs.readFile('./date/a.txt','utf8',function(err,data){if(err){//失败了,承诺容器中的任务失败了//把容器中的Pending状态改为成功Rejected//调用reject就相当于调用了then方法的第二个参数函数reject(err);}else{//承诺任务中的任务成功了//把容器的Pending状态改为成功Resolved//也就是说这里调用 的resolve方法实际上就是then方法传递的哪个funcionresolve(data);}})})varp2=newPromise(function(resolve,reject){fs.readFile('./date/b.txt','utf8',function(err,data){if(err){reject(err);}else{resolve(data);}})})varp3=newPromise(function(resolve,reject){fs.readFile('./date/c.txt','utf8',function(err,data){if(err){reject(err);}else{resolve(data);}})})//p1就是那个承诺//当p1成功了然后(then)做指定的操作//then方法接收的function就是容器中的resolve函数p1.then(function(data){console.log(data);//当p1读取成功的时候//当前函数中的return的结果就可以再后面的then中function接收到//当return 1 2 3 后面就接收到123//我们可以return一个Promise对象returnp2;},function(err){console.log('读取文件失败',err);}).then(function(data){console.log(data);returnp3;},function(err){console.log(err);}).then(function(data){console.log(data);},function(err){console.log(err);})
1 过滤
三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素。
其他过滤方法,比如filter()和not()允许您选取匹配或不匹配某项指定标准的元素。这个过滤指的就是相当于css中的选择器,如:id选择器,类选择器,标签选择器,子代选择器等
/*
filer 过滤 对已经获取到的网页元素进行过滤
not filer的反义词
has 拥有,直接判定子节点中是否有符合条件的元素
*/$(function(){$("div").filer(".box").css("backgroundColor","orange")$("div").not(".box").css("backgroundColor","orange")$("div").has(".box").css("backgroundColor","orange")})
2 查找
方法说明
prev()查找当前兄弟节点中的上一个节点
next()查找当前兄弟节点中的下一个节点
eq()通过已经获取到元素的伪数组下标获取指定元素的节点
$(function(){$("h3").prev().css("backgroundColor","red")$("h3").next().css("backgroundColor","bule")$("li").eq(3).css("backgroundColor","orange")// 获取所有li标签中下标为3的元素$("li:eq(4)").css("backgroundColor","orange")// 获取所有li标签中下标为4的元素})
3 设置和修改行间属性 attr
$(function(){// 获取属性值alert($("#div1").attr("id"))alert($("#div1").attr("class"))// 设置属性值$("#div1").attr("title","world")$("#div1").attr("calss","box2")// 一次性修改多条属性$("#div1").attr({title:"world",class:"xxx",yyy:"zzz"})})
4 class 属性添加与删除
Class可以写多个css样式,addClass()可以添加class
removeClass()可以删除class
$(function(){// 添加css 样式$("#div1").addClass("box3 box4 box2")// 删除css 样式$("#div1").removeClass("box3 box2")})
5 元素宽高获取
方法说明
width() 与 height()width
innerWidth() 与 innerHeight()width + padding
outerWidth() 与 outerHeight()width + border + padding
$(function(){alert($("#div1").width())// widthalert($("#div1").innerWidth())// width + paddingalert($("#div1").outerWidth())// width + border + paddingalert($("#div1").outerWidth(true))// width + border + padding + margin})
6 节点操作
下面每种标签的方法右边写着另外一种方法 作用是写入的选择器标签相反而已,一般用于方便其他样式的操作,方便jquery的链式操作
insertBefore() before()
insertAfter() after()
appendTo() 插入到子节点的末尾 appendChild(类似于js的方法)
append()插入到某节点
prependTo() 插入到子节点的首位 prepend()
remove()删除元素节点
并不会保留这个元素节点上之前的事件和行为
detach() 删除元素节点
会保留这个元素节点上之前的事件和行为
$(function(){// 找到span节点插入到div的前面$("span").insertBefore($("div"))// 找到div节点,插入到span节点的后面$("div").insertAfter($("span"))// 找到span节点,插入到div节点的子节点的末尾$("span").appendTo($("div"))})
7 事件绑定
on() 方法
给一个事件添加函数
$("div4").on("click",function(){alert("hello")})
同时给多个事件添加一个函数, 多个事件之间可以通过空格隔开
vari=0$("div4").on("click mouseover",function(){$(this).html(i++)})
给不同的事件添加不同的函数
$("div4").on({click:function(){alert("点击")},mouseover:function(){$(this).css("backgroundColor","orange")},mouseout:function(){$(this).css("backgroundColor","blue")}})
事件委托
// 第二个参数,是触发对象的选择器$("ul").on("click","li",function(){$(this).css("backgroundColor","red")})
取消事件绑定 off 方法
$("#cancel").click(function(){$("#div1").off()// 取消所有事件上面的所有函数$("#div1").off("click")// 取消某一个事件下的所有函数$("#div1").off("click",show)// 取消某一个事件下指定的函数})
8 窗口滚动高度获取 scrollTop
$(function(){$(document).click(function(){alert($(window).scrollTop())// 输出滚动高度})})
9 事件阻止(事件冒泡、默认行为阻止)
ev pageX which
preventDefault stopPropagation
$(function(){$("div").click(function(ev){alert(this.id)ev.stopPropagation()})$("a").click(function(ev){// ev.preventDefault()// ev.stopPropagation()// 既阻止事件冒泡,又阻止默认行为 returnfalse})})
10 键盘事件
鼠标事件 与 键盘事件 keydown事件下用which可以输出键盘按下的键码支持所有按键包括功能键。 keypress事件下 用which可以输出键盘按下的字符码 只支持字符键功能键不能输出
ev pageX
which
鼠标事件: button
左键
滚轮
右键
keydown: keyCode 键码
keypress: charCode 字符码
$(window).keypress(function(){alert(ev.which)// 获取到字符码})
11 获取鼠标的位置值 pageX 与 pageY
$(window).keypress(function(){alert(ev.pageX+","+ev.pageY)// 带滚动距离alert(ev.clientX+","+ev.clientY)// 可视窗口alert(ev.which)})
12 元素top与left值获取
方法说明
offset()直接获取当前元素,距离最左边的距离,margin不算数
position()直接获取,当前元素,距离第一个有定位父节点的距离,margin算在内
offsetParent()查找第一个有定位的父节点,如果父节点没有定位就继续往上找,最终到html节点
$(function(){alert($("#div2").offset().left)alert($("#div2").position().left)$("#div2").offsetParent().css("backgroundColor","yellow")})
13 元素内容获取
val() 获取/ 设置表单元素的值
size() 输出,获取网页元素的个数,类似于js中的 length
each() 用来循环将元素节点内容赋值成下标值
html() 获取元素的里面的内容
text() 获取元素的纯文本内容
attr() 获取标签行内属性值
css() 获取元素的style里面的属性
$("input").each(function(index,item){$(item).val(index)})
14 jquery特效函数
hide()隐藏show()显示 淡入淡出 这些效果都在hover移入移出方法下使用
hide(动画持续的毫秒数,回调函数,动画结束的时候执行)
$(function(){$("#div1").hover(function(){$("#div2").hide(2000,function(){$("#div1").html("移入")})},function(){$("#div2").show(2000,function(){$("#div1").html("移出")})})})
slideDown()
slideUp() 动画效果是卷帘效果
fadeIn() 淡入
fadeOut() 淡出
fadeTo (动画持续时间, 透明度0 ~ 1,回调函数)
15 jquery的 animate 动画
默认的运动形式是 满快慢
匀速 linear
满快慢 swing
扩展更多animate 的运动形式:
引入jquery-ui
$(function(){$("#div1").hover(function(){$("#div2").animate({width:300,height:300,opacity:0.5},4000,function(){$("#div1").html("移入")})},function(){$("#div2").animate({width:200,height:200,opacity:1},4000,function(){$("#div1").html("移出")})})})
Jquery引入后jquery可以设置颜色class颜色样式删除与添加时候的动画效果,有了jqueryUi以后,addClass 和 removeClass 就变成了增强版方法
$("button").eq(0).click(function(){$("#div1").addClass("box",4000)})$("button").eq(0).click(function(){$("#div1").removeClass("box",4000)})
Jquery停止动画函数 stop() finish()
$("#div1").click(function(){$("#div1").animate({width:300},2000).animate({height:3000},2000)})$("#div1").click(function(){$("#div1").stop()// 停止第一个动画,当时后续动画正常启动$("#div1").stop(true)// 停止所有动画$("#div1").stop(true,true)// 停止所用动画,并且将当前正在进行的动画,直接到达目的值$("#div1").finish()// 停止所有动画,并且将所有的动画都达到目的值})
delay()延迟下一个动画执行的时间
() 里面传在需要延时多少时间后执行
$("#div1").click(function(){$("div1").animate({width;300},2000).delay(4000).animate({height:300},2000)})
16 元素节点获取
siblings() 用来除当前节点外,所有的兄弟节点
nextAll() prevAll()
parentsUntil() nextUntil( ) prevUntil()
$(function(){$("#p1").siblings().css("color","red")$("#p1").nextAll().css("color","red")$("#p1").prevAll().css("color","red")})
父节点的获取
方法说明
parent()获取父节点
parents()获取父节点 参数选择器
closest()必须传入参数,参数也是选择器,只获得一个符合条件的元素,从自己开始去查找
$(function(){$("#p1").parent().css("color","red")$("#p1").parents(".box").css("color","red")$("#p1").closest("#div1").css("color","red")})
克隆节点
方法说明
clone()默认只会克隆节点本身,并不会克隆我们元素节点的行为和事件
clone(true)既会克隆节点本身,还会克隆节点元素节点的行为和事件
$("button").click(function(){varnode=$("div1").clone(true)node.appendTo("#div2")})
多个选择器拼接
add() 可以将多个选择器拼接在一起
slice() slice(start, end) [start, end] 获取指定范围内获取的元素节点
$("div").add("span").add("ul li")$("ul li").sclice(1,4).css("color","red")
表单数据串联化
方法说明
serialize()将我们表单中的数据拼接成querystring(查询字符串)name1=value1&name2=value2
search()?name1=value1&name2=value2
querystring()name1=value1&name2=value2
serializeArray()将表单数据拼接成数组
$(function(){console.log($("input").serialize())})
主动触发事件
方法说明
trigger()主动触发
ev.data
ev.target(兼容后触发对象)
ev.type(输出事件类型)
$("#play").on("play",function(){alert("开始播放音乐")})$("#play").on("next",function(){alert("切换到下一首歌曲")})$("#button").eq(0).click(function(){$("#play").trigger("play")})$("#button").eq(1).click(function(){$("#play").trigger("next")})
17 对元素节点包装
方法说明
wrap()每个获取到的元素节点单独包装
wrapAll()整体包装
wrapInner()内部包装
unwrap()删除包装 删除上面一层包装,不包括body节点
$(function(){// 给页面上所有的span 节点加包装,直接Jq创建节点的代码$("span").wrap("<p class="box" title="hello"></p>")$("span").wrapAll("<p class="box" title="hello"></p>")$("span").wrapInner("<p class="box" title="hello"></p>")$("span").unwrap()// 没有参数})
18 cookie
$.cookie(name) 通过name取值
$.cookie(name, value) 设置name和value
$.cookie(name, value ,{
可选项 raw:truevalue不进行编码 默认falsevalue要进行编码的
})
$.cookie(name, null) 删除cookie
$.cookie("变种人","X教授",{expires:7,raw:true})
19 ajax 网络请求
$.ajax({type:"get",url:"https://api.asilu.com/weather/",data:{city:"深圳"},dataType:"jsonp",// 如果请求地址跨域,可以使用dataType来指定跨域的解决方式,这里使用了jsonpsuccess:function(data,statusText,xhr){// data 下载到的数据// statusText 下载的状态 success// xhr ajax对象consloe.log(data+","+statusText)},erorr:function(msg){consloe.log(msg)}})
load方法
将url传入以后,将下载到的数据直接填充到被选中元素的innerHTML中
$(function(){$("button").click(function(){$("div").load("2.txt")})})
get与post方法直接调用
$("button").eq(2).click(function(){$.post(1.post.php,{username:"tian",age:20,password:"123asd"},function(data,statusText,xhr){alert(data)})})
三、websocket通信协议
1 创建websocket对象
// H5 已经直接提供了websocket 的API,所以可以直接调用// 1.创建 WebSocket // 参数1: WebSocket 的服务地址varsocket=newWebSocket('ws://echo.websocket.org')
2 websocket事件
事件事件处理程序描述
openSocket.onopen连接建立时触发
messageSocket.onmessage客户端接收服务器端数据时触发
errorSocket.onerror通讯发生错误时触发
closeSocket.onclose连接关闭时触发
3 websocket方法
方法描述
Socket.send()使用连接发送数据
Socket.close()关闭连接
4 调用websocket对象事件与方法
// 2.open: 当和 WebSocket 服务连接成功时候触发socket.addEventListener('open',function(){div.innerHTML='连接服务成功'})// 3.主动的给websocket服务发送消息button.addEventListener('click',function(){varvalue=input.value socket.send(value)})// 4.接收websocket服务的数据 socket.addEventListener('message',function(e){console.log(e.data);div.innerHTML=div.innerHTML+','+e.data})// 5.当websocket服务断开是事件socket.addEventListener('close',function(){div.innerHTML='服务断开连接'})
5 使用nodejs开发websocket服务
使用nodejs开发websocket需要依赖一个第三方包。Nodejs Websocket
// 1.导入nodejs-websocket包constws=require("nodejs-websocket")constPORT=3000// 2.创建一个sever// 2.1 如何处理用户请求// 每次只要有用户连接,函数就会被执行,会给当前连接用户创建一个 connect 对象constserver=ws.createServer(connect=>{console.log('有用户连接');// 每当接收到用户传递过来的数据,这个text事件会被触发connect.on('text',(data)=>{console.log('接收到了用户对的数据',data);// 给用户一个响应的数据// 对用户放过来的数据,把小写转换成大写,并且拼接一点内容connect.send(data.toUpperCase()+'!!!')})// 只要websocket链接断开,close 事件就会触发connect.on('close',()=>{console.log('连接断开');})// 注册一个error,处理用户的错误信息connect.on('error',()=>{console.log('用户连接异常');})})server.listen(PORT,()=>{console.log('websocket服务启动成功,监听端口为:'+PORT);})
6 简单聊天室代码
// 1.导入nodejs-websocket包constws=require("nodejs-websocket")constPORT=3000constTYPE_ENTER=0constTYPE_LEAVE=1constTYPE_MSG=2/*
分析:
消息不应该是简单的字符串
这个消息应该是一个对象
type:消息的类型, 0:表示用户进入聊天室消息 1:表示用户离开聊天室的消息 2:正常的聊天消息
msg:消息的内容
time:聊天的具体时间
*/// 记录当前连接上来的总的用户数量letcount=0// conn每个连接到服务器的用户,都会有一个 conn 对象constserver=ws.createServer(conn=>{console.log('新的连接');count++conn.username=`用户${count}`//1. 告诉所用用户,有人加入聊天室broadcast({type:TYPE_ENTER,msg:`${conn.username}进入聊天室`,time:newDate().toLocaleTimeString()})// 接收到了浏览器的数据conn.on('text',data=>{// 2.当我们收到某个用户的信息的时候,告诉所有用户,发送的消息的内容 是什么broadcast({type:TYPE_MSG,msg:`${conn.username}:${data}`,time:newDate().toLocaleTimeString()})})// 关闭连接的时候触发conn.on('close',data=>{console.log('关闭连接');count--broadcast({type:TYPE_LEAVE,msg:`${conn.username}退出聊天室`,time:newDate().toLocaleTimeString()})// 3.告诉所有的用户,有人离开了聊天室})// 发生异常,触发conn.on('error',data=>{console.log('发生异常');})})// 给所有的用户发送消息functionbroadcast(msg){// server.connections : 表示所有的用户 server.connections.forEach(item=>{item.send(JSON.stringify(msg))})}server.listen(PORT,()=>{console.log('websocket服务启动成功,监听端口为:'+PORT);})
7 socket.io框架(基于websocket)
框架说明文档地址:https://socket.io/
node后端:
// 创建http服务器 consthttp=require('http')varfs=require('fs')constapp=http.createServer()app.on('request',(req,res)=>{fs.readFile('./index.html',function(err,data){if(err){res.writeHead(500)returnres.end('Error loading')}res.writeHead(200)res.end(data)})})app.listen(3000,()=>{console.log('listening on *:3000');});constio=require('socket.io')(app);// 监听了用户连接 的事件// socket 表示用户连接 // socket.emit 表示触发某个事件 如果需要给浏览器发送数据,需要触发浏览器注册的某个事件// socket.on 表示注册某个事件 如果需要获取浏览器的数据,需要注册一个事件,等待浏览器触发io.on('connection',socket=>{console.log('新用户连接了');// sockrt.emit 方法表示给浏览器发送数据// 参数1:事件的名字// socket.emit('send', {name: 'zs'})// 参数1:事件名: 任意// 参数2: 获取到的数据socket.on('hehe',data=>{console.log(data);socket.emit('send',data)})})
HTML前端:
<!DOCTYPEhtml><html lang="en"><head><title></title><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1"><link href="css/style.css"rel="stylesheet"></head><body>hahha<script src="/socket.io/socket.io.js"></script><script>// 连接socket服务// 参数:服务器地址varsocket=io('http://localhost:3000')// 接收服务器返回的数据// socket.on('send', data => {// console.log(data);// })socket.emit('hehe',{name:'zs',age:'23'})socket.on('send',function(data){console.log(data);})</script></body></html>
基于express框架的socket.io:
constapp=require('express')();consthttp=require('http').Server(app);constio=require('socket.io')(http);app.get('/',(req,res)=>{res.sendFile(__dirname+'/index.html');});io.on('connection',(socket)=>{socket.on('hehe',function(data){console.log(data);})});// 启动服务器 http.listen(3000,()=>{console.log('listening on *:3000');});
disconnect:后端监听用户断开事件
四、常用函数
filter过滤
过滤数组中的数据并返回过滤后的数据
cart=cart.filter(v=>v.checked);
forEach 遍历
遍历数组中的对象
lettotalPrice=0;lettotalNum=0;cart.forEach(v=>{totalPrice+=v.num*v.goods_price;totalNum+=v.num;})
map 映射
给数组中添加新的属性与属性值
constres=awaitrequest({url:"/my/orders/all",data:type});this.setData({orders:res.orders.map(v=>({...v,create_time_cn:(newDate(v.create_time*1000).toLocaleDateString())}))
Some()条件遍历
遍历数组中的属性值进行条件判断,只要遇到一个判断为true就终止函数遍历,返回true。
// 1 获取缓存中的商品收藏数组letcollect=wx.getStorageSync("collect")||[];// 2 判断当前商品是否被收藏letisCollect=collect.some(v=>v.goods_id===this.GoodsInfo.goods_id);
findindex()索引遍历
获取数组中可以匹配项的索引,如果在数组中没有找到,返回值为-1
letindex=collect.findIndex(v=>v.goods_id===this.GoodsInfo.goods_id);
splice() 数组修改删除
表示删除数组中的数据 index为需要开始删除的索引,1 表示删除一条
collect.splice(index,1);
split() 字符分割
根据传入函数中的字符将字符串分割并返回成数组
varstr='asdfgdh'letindex=str.split('d')console.log(index);// ["as", "fg", "h"]
trim()去字符两边空格
去掉字符串两边的空格 ps: trimStart() 去除头部空白 trimEnd() 去除尾部空白
value.trim()
replace() 修改字符
匹配字符串中的对应字符并修改 (goods需要匹配字符,goodsList为需要修改为的数据)
url=url.replace("/goods/","goodsList")
reduce() 求和函数
functionsum(...args){returnargs.reduce((p,c)=>p+c,0);}sum(1,2,3,4)
indexOf() 匹配字符下标
匹配字符返回遍历到的字符下标
varstr='asdfgh'letindex=str.indexOf('f')console.log(index);// 3
字符查找
includes():查找对象属性字符串中是否有相应的“字符” 返回true或者false
startsWith()字符串中以传入函数中的字符开头返回true
endsWith()字符串中以传入函数中的字符结尾返回true
if(params.url.includes("/my/")){// 拼接header 带上tokenheader["Authorization"]=wx.getStorageSync("token");}
reverse() 反转数组
varatr=[1,2,3,4]atr.reverse()console.log(atr);// [4, 3, 2, 1]
find() 查找函数
查找对数组中的值一次去匹配条件,如果符合返回符合的字符
vararr=['zhangsan','lisi','wangwu']varres=arr.find((item)=>{returnitem=='zhangsan'})console.log(res);// zhangsan
flat() 数组扁平化
constarr=[1,[2,[3,[4,5]]],6]constres=arr.flat(Infinity);console.log(res);// [1,2,3,4,5,6]
结构赋值技巧
用数组的值作为要生成对象的属性名(也可以是对象赋值时都需要写在 [ ] 里面)
vararr=['ews','sds']functionadd(i){if(!i){return{[arr[0]]:'test'}}else{return{[arr[1]]:'test'}}}console.log(add(1));// {sds: "test"}
五、typescript篇
1. ts类型
类型例子描述
number1, -33, 2.4数字
string‘hello’字符串
booleantrue, false布尔值 true 或 false
字面量其本身 let a: 10;限制变量的值就是该字面的值
any*任意类型
unknown*类型安全的any
void空值(undefined)没有值(或undefined)
never没有值不能是任何值
object{name:'cola'}任意js对象
array[1,2,3]数组
tuple[4,5]元素,Ts新增类型,固定长度数组
enumenum{A, B}枚举,Ts中新增类型
2 变量赋值
leta:number;letb:number=123;letc=123// 联合变量赋值letc:boolean|string// 类型是布尔值或字符串c=truec='heloo'// & 表示同时,即是字符串又是数字letj:{name:string}&{age:number}j={name:'孙悟空', age:21}// 声明变量如果不指定类型,则Ts解析器会自动判断变量的类型尾any,(隐式的any)letd;d=10;d='hello'd=true// 类型断言,告诉解析器变量的实际类型s=easstring;s=<string>e;// viod 用来表示空,以函数为例,就表示没有返回值functionfn():void{}// never 表示永远不会返回结果 (可以用来处理程序报错)functionfn():never{thrownewError('报错了')}// 创建对象leta:object;// 不建议a={}// 不建议letb:{name:string,age?:number}// 对象中的属性指定类型,属性名后面加问号表示此参数为可选属性b={name:'孙悟空', age:12}letc:{name:string,[propName:string]:any}// [propName: string] 表示任意字符串,它可以是任意类型c={name:'猪八戒',age:12,gender:'男'}letd:(a:number,b:number)=>number;// 设置函数结构的类型声明,传入值为数字,返回值为数字,d=function(n1:number,n2:number):number{returnn1+n2;}// 数组lete:string[]// 表示字符串数组e=['a','b','c']letg:Array<number>// 与上面声明方式一样,这是数字类型数组// tuple元组 固定长度的数组leth:[string,string]h=['hello','abc']// enum 枚举 enumGender{Male=0,// 男Female=1// 女}leti:{name:string,gender:Gender}i={name:'孙悟空', hender:Gender.Male// 性别: 男}// 类型别名typemytype=1|2|3|4|5;letk:1|2|3|4|5;letl:1|2|3|4|5;letm:mytype// 这样m的类型也是 1 | 2 | 3 | 4 | 5;
3.函数传参赋值:
function sum(a:number,b:number):number{return a + b;}const result = sum(123,234)
4.TS编译选项
tsconfig.json 配置
{/*
include 用来指定那些 ts 文件需要被编译 ** 任意目录 * 任意文件
exclude 用来指定那些 ts 文件不许被编译
默认值: ["node_modules","bower_components","jspm_packages"]extends 定义被继承的配置文件 files 指定被编译的文件列表,只有需要编译文件少时才会用到 compilerOptions 编译器的选项 */"include":["./src/**/*"],// "exclude":[// "./src/hello/*"// ],"compilerOptions":{// 用来指定ts被编译为es的版本"target":"ES6",// 指定要使用模块化的规范"module":"system",// 用来指定项目中要使用的库// "lib":[],// 指定编译后文件所在的目录"outDir":"./dist",// 设置outfile 后,所有全局作用域中的的代码会合并到同一个 文件中// "outFile":"./dist/app.js",// 是否对js进行编译,默认是false"allowJs":true,// 是否检查js代码"checkJs":false,// 是否移除注释"removeComments":true,// 不生成编译后的文件"noEmit":false,// 当有错误的时候不生成编译文件"noEmitOnError":true,// 所有严格检查的总开关"strict":true,// 用来设置编译后的js文件是否使用严格模式,默认是false"alwaysStrict":true,// 不允许隐式的Any类型"noImplicitAny":true,// 不允许不明确类型的this"noImplicitThis":true,// 严格的检查空值"strictNullChecks":true}}
5.webpack打包TS
5.1 tsconfig.json 配置
{"compilerOptions":{"module":"ES2015","target":"ES2015","strict":true}}
5.2 webpack.config.js 配置
// 引入一个包constpath=require('path')// 引入html插件constHTMLWebpackPlugin=require('html-webpack-plugin')// 引入clean 插件 打包时先清除dist目录const{CleanWebpackPlugin}=require('clean-webpack-plugin')module.exports={// 指定入口文件entry:'./src/index.ts',// 指定打包文件所在的目录output:{// 指定打包目录path:path.resolve(__dirname,'dist'),// 打包后文件的名字filename:'bundle.js',// 告诉webpack不使用箭头函数environment:{arrowFunction:false}},// 指定webpack 打包时要使用的模块module:{// 指定加载规则rules:[{// test 指定规则生效的文件test:/\.ts$/,// 要使用的loadderuse:[// 配置babel 做兼容{// 指定加载器loader:"babel-loader",// 设置babeloptions:{// 设置预定义的环境presets:[[// 指定环境插件"@babel/preset-env",// 配置信息{// 要兼容的目标浏览器targets:{"chrome":"58","ie":"11"},// 指定corejs版本"corejs":"3",// 使用corejs的方式 "usage" 表示按需加载"useBuiltIns":"usage"}]]}},'ts-loader'],// 要排除的文件exclude:/node-modules/}]},// 配置wenpack插件plugins:[// 打包前删除dist目录newCleanWebpackPlugin(),// 自动构建html文件newHTMLWebpackPlugin({// title: "这是一个自定义的title"template:"./src/index.html"}),],// 用来设置引用模块resolve:{extensions:['.ts','.js']}}
5.3 依赖包
{"name":"part2","version":"1.0.0","description":"","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack","start":"webpack serve --open chrome.exe"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@babel/core":"^7.14.3","@babel/preset-env":"^7.14.2","babel-loader":"^8.2.2","clean-webpack-plugin":"^4.0.0-alpha.0","core-js":"^3.12.1","html-webpack-plugin":"^5.3.1","ts-loader":"^9.2.1","typescript":"^4.2.4","webpack":"^5.37.1","webpack-cli":"^4.7.0","webpack-dev-server":"^3.11.2"}}
6 class 类
6.1 类的基本使用
// 使用class 关键字来定义/*
对象包括包含两个部分
属性
方法
*/classPerson{/*
直接定义的属性是实例属性,需要通过对象的实例去访问:
const per = new Person()
per.name
使用static开头的是静态属性
Person.age
readonly 开头的属性表示一个只读属性
*/// 定义实例属性readonlyname:string='孙悟空'// 在属性前使用static关键字可以定义类属性(静态属性)staticreadonlyage:number=18// 定义方法sayHello(){console.log('hello');}}constper=newPersonconsole.log(per);console.log(Person.age);per.sayHello()
6.2 构造函数
classDog{name:stringage:number// 构造函数会在对象创建的时候调用constructor(name:string,age:number){// 在实例方法中,this就表示当前的实例// 在构造函数中当前对象就是新建的哪个对象// 可以通过this向新建的对象中添加属性this.name=namethis.age=age// console.log(this);}back(){// alert('旺旺旺')// 在方法中可以通过this来表示当前调用方法的对象console.log(this);}}constdog=newDog('小黑',12)constdog2=newDog('小白',23)console.log(dog);console.log(dog2);dog.back()
7 继承
7.1 继承使用 (extends关键字)
(function(){// 定义 Animal 类classAnimal{name:stringage:numberconstructor(name:string,age:number){this.name=namethis.age=age}sayHello(){console.log('动物在叫');}}/*
Dog extends Animal
此时,Animal被称为父类,Dog被称为子类
使用继承后,子类会拥有父类所有的方法和属性
如果在子类中添加了和父类相同的方法,则子类方法会覆盖父类的方法 ,这种叫方法重写
*/// 定义一个狗的类// 使Dog类继承Animal类classDogextendsAnimal{run(){console.log(`${this.name}再跑`);}}// 定义一个猫的类// 使Cat类继承Animal类classCatextendsAnimal{sayHello(){console.log('喵喵喵');}}constdog=newDog('旺财',5)constcat=newCat('咪咪',3)console.log(dog);dog.sayHello()dog.run()console.log(cat);cat.sayHello()})()
7.1 super关键字
(function(){class Animal{name:string constructor(name:string){this,name = name}sayHello (){console.log('动物在叫');}}class Dog extends Animal{age:number constructor (name:string,age:number){// 如果在子类中写了构造函数,此时在子类的构造函数中必须对父类的构造函数调用super(name)// 调用父类构造函数this.age = age}sayHello (){// 在类的方法中 super 就表示当前类的父类super.sayHello()}}const dog = new Dog('旺财',23) dog.sayHello()})()
8 抽象类 (abstract 关键字)
(function(){/*
以 abstract 开头的类是抽象类
抽象类和其他的类区别不大,只是不能用来创建对象
抽象类就是专门用来被继承的类
抽象类中可以添加抽象方法
*/abstract class Animal{name:string constructor(name:string){this,name = name}// 定义一个抽象方法// 抽象方法使用 abstract 开头,没有方法体// 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写abstract sayHello ():void}class Dog extends Animal{sayHello (){console.log('旺旺旺旺');}}class Cat extends Animal{// 直接这个不重写 父类定义的抽象方法就会报错}const dog = new Dog('旺财') dog.sayHello()})()
10 接口 (interface、implements 关键字)
(()=>{// 描述一个对象类型typemyType={name:string,age:number}constobj:myType={name:'sss',age:23}/*
接口用来定义一个类结构, 用来定义一个类中应该包含那些属性和方法
同时接口也可以当成类型声明去使用
*/interfacemyInterface{name:string,age:number}interfacemyInterface{gender:string}// 接口可以在定义类的时候去限制类的结构// 接口中的所有属性都不能有实际的值// 接口只定义对象的结构,而不考虑实际值// 在接口中所有方法都是抽象方法interfacemyinter{name:stringsayHello():void}/*
定义类时,可以使类去实现一个口接口
实现接口就是使类满足接口的要求
*/classMyClassimplementsmyinter{name:stringconstructor(name:string){this.name=name}sayHello(){console.log('大家好'+this.name)}}constmyCalss=newMyClass('李四')myCalss.sayHello()})()
11 属性的封装 (public、private关键字 )
(()=>{// 表示人的类classPerson{// Ts 可以在属性前添加属性的修饰符/*
public 修饰的属性可以在任意位置修改、访问(包括子类) 默认值
private 私有属性,只能在类的内部修改 访问
- 可以通过在类中添加方法使得私有属性可以访问
protected 受保护的,只能到当前类和当前的子类中访问
*/private_name:string;private_age:number;constructor(name:string,age:number){this._name=namethis._age=age}// 定义方法,用来获取name属性getName(){returnthis._name}// 定义一个方法用来设置name属性setName(value:string){this._name=value}getAge(){returnthis._age}setAge(value:number){// 判断年龄是否合法if(value>=0){this._age=value}}// TS 中设置getter方法的方式getname(){returnthis._name}setname(value:string){this._name=value}getage(){returnthis._age}setage(value:number){if(value<0){return}this._age=value}}constpreson=newPerson('孙悟空',23)/*
现在属性是在对象中设置的,属性可以任意修改
属性可以任意修改将会导致对象中的数据变得非常不安全
*/// preson.setName('租八戒')// preson.setAge(-33)preson.name='租八戒'preson.age=-3console.log(preson);// _name: "租八戒", _age: 23})()
12 泛型
// function fn(a: number):number {// return a// }/*
在定义函数或是类时,如果遇到类型不明确就可以使用泛型
*/functionfn<T>(a:T):T{returna}// 可以直接调用具有泛型的函数fn(10)// 不指定泛型,TS可以自动对类型进行推断fn<string>('hello')// 指定泛型functionfn2<T,K>(a:T,b:K):T{console.log(b)returna}fn2(123,'hello')interfaceInter{length:number}// T extends Inter 表示泛型 T 必须是 Inter 实现类(子类)functionfn3<TextendsInter>(a:T):number{returna.length}fn3('123')fn3({length:232})classMyClass<T>{name:Tconstructor(name:T){this.name=name}}constmc=newMyClass<string>('询')
14 命名空间 (namespace)
namespceA{interfaceAnmal{name:string;eat():viod}exportclassDogimplemnts Anmal{name:string;constructor(theName:string){this.name=theName}eat(){console.log(${this.name}吃狗粮)}}}namespceB{interfaceAnmal{name:string;eat():viod}exportclassDogimplemnts Anmal{name:string;constructor(theName:string){this.name=theName}eat(){console.log(${this.name}吃狗粮)}}}vard=newA.Dog('张三')d.eat()varf=newB.Dog('李四')f.eat()
15 装饰器
装饰器是一种特殊的声明,它能够被附加到类声明,方法,属性,或则参数上,可以修饰行为
常见装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器
装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)
类装饰器:在类型声明前被声明,类装饰器应用于类构造函数,可用来监视,修改或替换类定义,传入一个参数
// 类装饰器functionlogClass(params:any){console.log(params);// params 就是当前类params.prototype.apiUrl='动态扩展的属性'params.prototype.run=function(){console.log('我是一个run方法');}}@logClassclassHttpClient{constructor(){}getData(){}}varhttp:any=newHttpClient()console.log(http.apiUrl);http.run()
类装饰器工厂:
functionlogClass(params:string){returnfunction(target:any){console.log(target);console.log(params);target.prototype.apiUrl=params}}@logClass('http://www.yes.com')classHttpClient{constructor(){}getData(){}}varhttp:any=newHttpClient()console.log(http.apiUrl);
属性装饰器:
// 属性装饰器functionlogProperty(params:any){returnfunction(target:any,attr:any){console.log(target);console.log(attr);target[attr]=params}}classHttpClient{@logProperty('http://weqweqwe.com')publicurl:any|undefinedconstructor(){}getData(){console.log(this.url);}}varhttp:any=newHttpClient()http.getData()