javascript与typescript语法总结
JavaScript常见输出
window.alert() 弹出框警告
document.write() 将内容写到HTML文档中
innerHTML 写入到HTML元素中
console.log() 控制台输出
1 函数中的arguments使用
每个函数内部都有一个 arguments ,系统内置的。
arguments是用来储存实际传入的参数
//求传入任意数字的和? var sum = 0;//求和的数 function sumFunction(){ for(i=0;i<arguments.length;i++){ //arguments.length代表当前输入已存储参数的个数。 sum += arguments[i]; } return sum; } alert(sumFunction(1,2,3,4,5,6));
2 函数的作用域
任何程序运行时候都要占用空间,函数调用的时候也要去占用空间
垃圾回收机制:调用完函数之后,系统会分配对应的空间给这个函数使用(空间大小一般由函数里声明的变量和形参决定),当函数使用完毕以后,这个内存会被释放,还给系统。
在函数内部声明的变量和形参是属于当前函数的内存空间。
内存管理机制:在函数中声明的变量和形参,会随着函数的调用被创建,随着函数的调用结束而销毁。在函数中声明的变量和形参,有效范围是当前函数(当前函数的大括号内),作用域,局部作用域。
var a = 10,b = 20; // 声明在全局的变量叫全局变量 function show(a){ var b = 100; // 在函数内部声明,局部变量 a += 5; alert(a + "," + b); }
3 函数递归
满足以下三个特点就是递归:
函数自己调用自己
一般情况有参数
一般情况下有return
注:递归可以解决循环能做的所有事情,有一些循环不容易解决的事情,递归也能解决。
//计算1~n的和? //正常函数写法 function sum(n){ var res = 0; for(i=1;i<=n;i++){ res += i; } return res; } alert(sum(100)); //递归写法 /* 方法:1.首先去找临界值,即无需计算,获得的值。 2.找这一次和上一次的关系。 3.假设当前函数已经可以使用,调用自身算上一次。 sum(100)== sum(99)+ 100; sum(n)== sum (n-1)+n; */ function sum(n){ if(n == 1){ return 1; } return sum(n-1)+n; } alert(sum(100));
4 函数闭包
满足以下特点的叫做闭包
函数嵌套函数
内部函数使用外部的形参和变量
被引用的形参和变量就不会被 【垃圾回收机制所回收,使内部函数的变量常驻内存中】
window.onload = function(){//闭包实现按钮遍历完后,点击按钮输出对应的键值。 var oBtn = document.getElementsByTagName("button"); for(var i = 0;i < oBtn.length;i++){ oBtn[i].onclick = (function(index){ return function(){ 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()归并var arr = [34,65,33,87,24,56]var res = arr.reduce((prev, next, index, arr) => { console.log(prev + "," + next); return prev + 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 正则表达式
/* 敏感词过滤 */ var arr = [/靠/ig,/tmd/ig,/nm/ig,/cao/ig]; function btnClick(){ var oTxt = document.getElementById("txt1"); var oMsg = document.getElementById("msg"); var oValue = oTxt.value; for(i=0;i<arr.length;i++){ oValue = oValue.replace(arr[i],"*"); } oMsg.innerHTML = oValue; oTxt.value = ''; }
9 对象方法
delete 关键字 删除对象属性或者方法
var obj = { name: 'zhangsan', age: 23}delete obj.age console.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) | 开平方 |
日期对象
// 获取当前时间var timeDate = new Date()conlose.log(tiemDate)// 传入时间初始化var timeDate = new Date("2000-01-01")var timeDate = new Date("2000/01/01")// 传入参数顺序 年 月 日 时 分 秒 毫秒 var timeDate = new Date(2000,0,1,8,30,50)// 可以直接传入某一时间距离1970年1月1日至今的毫秒数var timeDate = new Date()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 方法
var person = { username: "zhangsan", age: 18, sex: "男"}for (var i in person) { document.write("对象遍历:" + i + "," + person[i])}
10 setInterval定时器
格式:
var timer = setInterval(函数,毫秒数)clearInterval(timer) // 取消定时器
功能:每隔对应毫秒数,执行一次传入的函数
11 Bom对象
系统对话框
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
alert() | 无 | 无 | 弹出警告窗 |
confirm() | 无 | 确认返回true,取消 false | 带取消和确定的提示框 |
prompt() | 1.面板显示内容 2.输入框里面默认参数(可以不传) | 确认返回输入框内容,取消返回null | 带输入框的提示框 |
var res = prompt("请输入内容", 100);conlose.log(res)
open() 打开新窗口
参数1 | 参数2 | 参数3 |
---|---|---|
跳转的url 打开一个新窗口,加载url | 字符串,给打开的窗口起一个名字 | 一串特殊含义的字符串 |
function btnClick() { 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.parentNode | node的父节点 | 获取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 元素距离上面距离获取
var oDiv = document.getElemenByid("div1")alert(oDiv.offsetWidth) // width + border + padding (眼睛实际看到的宽度)
浏览器宽高获取
获取浏览器高度写法
var windowHeight = document.documentElement.clientHeight || document.body.clientHeight
获取浏览器宽度写法
var windowWidth = 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) { // 事件对象获取方式 固定写法 var e = ev || window.event alert(e)}
获取当前鼠标的位置
x坐标 | y坐标 | 说明 |
---|---|---|
clientX | clientY | 原点位置:可视窗口的左上角 |
pageX | pageY | 原点位置:整个页面的左上角(包含滚动出去的滚动距离) |
screenX | screenY | 原点位置:电脑屏幕的左上角 |
document.onmousedown = function(ev) { var e = 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) { var e = ev || window.event; var arr = [] 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) { var e = ev || window.event var which = e.which || e.charCode alert(which) // 可以通过判断 获取的到which 来 确认执行定义的函数}
Target目标触发
Target的指向就是触发当前事件的元素,this永远指向当前函数的主人。
var oUl = document.getElementById("ul1")oUl.onclick = function (ev) { var e = ev || window.event var target = e.target || window.event.srcElement alert(this.tagName) alert(target.innerHTML)}
阻止事件冒泡
有浏览器兼容问题
cancelBubble = true
stopPropagation()
var aDivs = document.getElementsByTagName("div")for(var i = 0;i < aDivs.length;i++) { aDivs[i].onclick = function(ev) { var e = ev || window.event alert(this.id) cancelBubble = true // 阻止冒泡 stopPropagation() // 阻止冒泡 }}
事件委托
实现步骤:
找到当前节点的父节点或则祖先节点
将事件添加到找到的这个父节点或则祖先节点上
找到触发对象,判断触发对象是否是想要的触发对象,进行后续操作
如下:li 委托 ul 将点击的li变成红色
var oUl = document.getElmentById("ul1")oUl.onclick = function(ev) { var e = ev || window.event var target = e.target || window.event.srcElement if(target = e.nodeName.toLowerCase() == "li") { target.style.backgroundColor = 'red' }}<ul id="ul1"> <li></li> <li></li> <li></li></ul>
事件监听器
removeEventListener() 删除事件中的函数
第一个参数:事件类型
第二个参数:删除函数的名称
格式:node.removeEventListener()
参数:
addEventListener() 给元素的事件添加函数
第一个参数:事件类型
第二个参数:绑定函数
第三个参数:布尔值
true 事件捕获
false 事件冒泡 默认
格式: node.addEventListener("click")
参数:
15 localStorage 本地存储
只能存储String
localStorage 对象
localStorage .setItem(name,value); 写入
localStorage .getItem(name); 读取
localStorage .removeItem(name); 删除
16 强制改变this指向
call() 方法
格式:函数名.call()
参数:
第一个参数:传入该函数this指向的对象,传入什么强制指向什么
第二个参数:将原函数的参数往后顺延一位
apply() 方法
格式:函数名.apply()
参数:
第一个参数:传入该函数this指向的对象,传入什么强制
第二个参数:数组 数组放我们原有所有参数
bind() 方法
预设this指向
function show(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 合并对象
将所有传入的对象,都合并到第一个对象中
var obj1 = {a: 10}var obj2 = {b:20,c:30}var obj3 = {d:40,f: ["hello","world", true]}Object.assign(obj1, obj2, obj3)
19 Map映射
会将重复的合并
// map 映射let map = new Map()// 添加数据map.set("张三","打鱼的")map.set("李四","种地的")map.set("王五","挖煤的")map.set("李四","打猎的")// 取值alert(map.get("王五"))
20 ajax网络请求
oBtn.onclick = function(){ //1、创建ajax对象 var xhr = null; try{ xhr = new XMLHttpRequest(); }catch(error){ xhr = new ActiveXObject("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、调用send xhr.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原型对象上,构造函数构造出来的对象共享原型上的所有方法
var arr1 = [10,23,244,34]var arr2 = [23,435,45,546,546]Array.prototype.sum = function () { var res = 0; for (var i = 0; i < this.length; i++) { res += this[i] } return res}console.log(arr1.sum());console.log(arr2.sum());console.log(arr1.sum == arr2.sum); // true
24 原型链继承
// Teddy.Prototype = Dog.Prototype() 非常错误的写法for (var funcName in Dog.Prototype) { Teddy.Prototype[funcName] = Dog.Prototype[funcName]}
25 __ proto __与instanceof 关键字
构造函数构造出来的对象,有一个属性__ proto ,指向构造出这个对象的构造函数的原型 ,每个对象的proto__属性指向自身构造函数的prototype;
instanceof 关键字
功能:判断某一个对象是否是这个构造函数构造出来
function Dog(obj) { this.obj = obj}var xiaobai = new Dog({ name: '小白', type: '比熊', age: 23})console.log(xiaobai instanceof Dog); // trueconsole.log(xiaobai instanceof Object); // true
26 Promise构造函数(解决回调地狱)
//在EcmaScript 6 中新增了一个API Promise//Promise是一个构造函数var fs = require("fs")//创建Promise容器//1.给别人一个承诺 // Promise容易一旦创建,就开始开始执行里面的代码var p1 = new Promise(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方法传递的哪个funcion resolve(data); } })})var p2 = new Promise(function(resolve,reject){ fs.readFile('./date/b.txt','utf8',function(err,data){ if(err){ reject(err); }else{ resolve(data); } })})var p3 = new Promise(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对象 return p2; },function(err){ console.log('读取文件失败',err); }) .then(function(data){ console.log(data); return p3; },function(err){ console.log(err); }) .then(function(data){ console.log(data); },function(err){ console.log(err); })
二、jQuery篇
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()) // width alert($("#div1").innerWidth()) // width + padding alert($("#div1").outerWidth()) // width + border + padding alert($("#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")})
同时给多个事件添加一个函数, 多个事件之间可以通过空格隔开
var i = 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() // 既阻止事件冒泡,又阻止默认行为 return false })})
10 键盘事件
鼠标事件 与 键盘事件 keydown事件下用which可以输出键盘按下的键码支持所有按键包括功能键。 keypress事件下 用which可以输出键盘按下的字符码 只支持字符键功能键不能输出
ev pageX
which
keydown: keyCode 键码
keypress: charCode 字符码
$(window).keypress(function() { alert(ev.which) // 获取到字符码})
鼠标事件: button
左键
滚轮
右键
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() { var node = $("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:true value 不进行编码 默认false value要进行编码的
})
$.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来指定跨域的解决方式,这里使用了jsonp success: 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 的服务地址var socket = new WebSocket('ws://echo.websocket.org')
2 websocket事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务器端数据时触发 |
error | Socket.onerror | 通讯发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
3 websocket方法
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
4 调用websocket对象事件与方法
// 2.open: 当和 WebSocket 服务连接成功时候触发 socket.addEventListener('open', function() { div.innerHTML = '连接服务成功' }) // 3.主动的给websocket服务发送消息 button.addEventListener('click', function() { var value = 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包const ws = require("nodejs-websocket")const PORT = 3000// 2.创建一个sever// 2.1 如何处理用户请求// 每次只要有用户连接,函数就会被执行,会给当前连接用户创建一个 connect 对象const server = 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包const ws = require("nodejs-websocket")const PORT = 3000const TYPE_ENTER = 0const TYPE_LEAVE = 1const TYPE_MSG = 2/* 分析: 消息不应该是简单的字符串 这个消息应该是一个对象 type:消息的类型, 0:表示用户进入聊天室消息 1:表示用户离开聊天室的消息 2:正常的聊天消息 msg:消息的内容 time:聊天的具体时间 */ // 记录当前连接上来的总的用户数量let count = 0// conn每个连接到服务器的用户,都会有一个 conn 对象const server = ws.createServer(conn => { console.log('新的连接'); count++ conn.username = `用户${count}` //1. 告诉所用用户,有人加入聊天室 broadcast({ type: TYPE_ENTER, msg: `${conn.username}进入聊天室`, time: new Date().toLocaleTimeString() }) // 接收到了浏览器的数据 conn.on('text', data => { // 2.当我们收到某个用户的信息的时候,告诉所有用户,发送的消息的内容 是什么 broadcast({ type: TYPE_MSG, msg: `${conn.username}:${data}`, time: new Date().toLocaleTimeString() }) }) // 关闭连接的时候触发 conn.on('close', data => { console.log('关闭连接'); count-- broadcast({ type: TYPE_LEAVE, msg: `${conn.username}退出聊天室`, time: new Date().toLocaleTimeString() }) // 3.告诉所有的用户,有人离开了聊天室 }) // 发生异常,触发 conn.on('error', data => { console.log('发生异常'); })})// 给所有的用户发送消息function broadcast(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服务器 const http = require('http')var fs = require('fs')const app = http.createServer()app.on('request', (req, res) => { fs.readFile('./index.html',function(err, data) { if(err) { res.writeHead(500) return res.end('Error loading') } res.writeHead(200) res.end(data) })})app.listen(3000, () => { console.log('listening on *:3000');});const io = 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前端:
<!DOCTYPE html><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服务 // 参数:服务器地址 var socket = 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:
const app = require('express')();const http = require('http').Server(app);const io = 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 遍历
遍历数组中的对象
let totalPrice = 0;let totalNum = 0;cart.forEach(v => { totalPrice+=v.num * v.goods_price; totalNum += v.num;})
map 映射
给数组中添加新的属性与属性值
const res = await request({url:"/my/orders/all",data:type}); this.setData({ orders:res.orders.map(v=>({ ...v, create_time_cn:(new Date(v.create_time * 1000).toLocaleDateString()) }))
Some()条件遍历
遍历数组中的属性值进行条件判断,只要遇到一个判断为true就终止函数遍历,返回true。
// 1 获取缓存中的商品收藏数组 let collect = wx.getStorageSync("collect")||[]; // 2 判断当前商品是否被收藏 let isCollect = collect.some(v=>v.goods_id===this.GoodsInfo.goods_id);
findindex()索引遍历
获取数组中可以匹配项的索引,如果在数组中没有找到,返回值为-1
let index = collect.findIndex(v => v.goods_id===this.GoodsInfo.goods_id);
splice() 数组修改删除
表示删除数组中的数据 index为需要开始删除的索引,1 表示删除一条
collect.splice(index,1);
split() 字符分割
根据传入函数中的字符将字符串分割并返回成数组
var str = 'asdfgdh'let index = str.split('d')console.log(index); // ["as", "fg", "h"]
trim()去字符两边空格
去掉字符串两边的空格 ps: trimStart() 去除头部空白 trimEnd() 去除尾部空白
value.trim()
replace() 修改字符
匹配字符串中的对应字符并修改 (goods需要匹配字符,goodsList为需要修改为的数据)
url = url.replace("/goods/","goodsList")
reduce() 求和函数
function sum(...args) { return args.reduce((p, c) => p + c, 0);}sum(1, 2, 3, 4)
indexOf() 匹配字符下标
匹配字符返回遍历到的字符下标
var str = 'asdfgh'let index = str.indexOf('f') console.log(index); // 3
字符查找
includes(): 查找对象属性字符串中是否有相应的“字符” 返回true或者false
startsWith() 字符串中以传入函数中的字符开头返回true
endsWith() 字符串中以传入函数中的字符结尾返回true
if(params.url.includes("/my/")){ // 拼接header 带上token header["Authorization"] = wx.getStorageSync("token");}
reverse() 反转数组
var atr = [1,2,3,4]atr.reverse()console.log(atr); // [4, 3, 2, 1]
find() 查找函数
查找对数组中的值一次去匹配条件,如果符合返回符合的字符
var arr = ['zhangsan','lisi','wangwu'] var res = arr.find((item) => { return item == 'zhangsan'})console.log(res); // zhangsan
flat() 数组扁平化
const arr = [1,[2,[3,[4,5]]],6]const res = arr.flat(Infinity); console.log(res); // [1,2,3,4,5,6]
结构赋值技巧
用数组的值作为要生成对象的属性名(也可以是对象赋值时都需要写在 [ ] 里面)
var arr = ['ews','sds'] function add (i) { if(!i) { return {[arr[0]]:'test'} } else { return {[arr[1]]:'test'} } } console.log(add(1)); // {sds: "test"}
五、typescript篇
1. ts类型
类型 | 例子 | 描述 |
---|---|---|
number | 1, -33, 2.4 | 数字 |
string | ‘hello’ | 字符串 |
boolean | true, 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新增类型,固定长度数组 |
enum | enum{A, B} | 枚举,Ts中新增类型 |
2 变量赋值
let a: number;let b:number = 123;let c = 123// 联合变量赋值let c: boolean | string // 类型是布尔值或字符串c = truec = 'heloo'// & 表示同时,即是字符串又是数字let j: { name: string } & { age: number } j = { name: '孙悟空', age: 21 }// 声明变量如果不指定类型,则Ts解析器会自动判断变量的类型尾any,(隐式的any)let d;d = 10;d = 'hello'd = true// 类型断言,告诉解析器变量的实际类型s = e as string;s = <string>e;// viod 用来表示空,以函数为例,就表示没有返回值function fn(): void {}// never 表示永远不会返回结果 (可以用来处理程序报错)function fn(): never{ throw new Error('报错了')}// 创建对象let a: object; // 不建议a = {} // 不建议let b: { name: string, age?:number } // 对象中的属性指定类型,属性名后面加问号表示此参数为可选属性b = { name: '孙悟空', age: 12 }let c: { name: string, [propName: string]: any } // [propName: string] 表示任意字符串,它可以是任意类型c = { name: '猪八戒', age: 12, gender: '男' }let d: (a: number, b: number) => number; // 设置函数结构的类型声明,传入值为数字,返回值为数字,d = function (n1: number, n2: number): number { return n1 + n2;}// 数组let e: string[] // 表示字符串数组e = ['a','b','c']let g: Array<number> // 与上面声明方式一样,这是数字类型数组 // tuple元组 固定长度的数组let h: [string, string] h = ['hello', 'abc']// enum 枚举 enum Gender { Male = 0, // 男 Female = 1 // 女}let i: { name: string, gender: Gender }i = { name: '孙悟空', hender:Gender.Male // 性别: 男} // 类型别名type mytype = 1 | 2 | 3 | 4 | 5;let k: 1 | 2 | 3 | 4 | 5;let l: 1 | 2 | 3 | 4 | 5;let m: 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 配置
// 引入一个包const path = require('path')// 引入html插件const HTMLWebpackPlugin = 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$/, // 要使用的loadder use: [ // 配置babel 做兼容 { // 指定加载器 loader: "babel-loader", // 设置babel options: { // 设置预定义的环境 presets: [ [ // 指定环境插件 "@babel/preset-env", // 配置信息 { // 要兼容的目标浏览器 targets: { "chrome": "58", "ie": "11" }, // 指定corejs版本 "corejs": "3", // 使用corejs的方式 "usage" 表示按需加载 "useBuiltIns": "usage" } ] ] } }, 'ts-loader' ], // 要排除的文件 exclude: /node-modules/ } ] }, // 配置wenpack插件 plugins: [ // 打包前删除dist目录 new CleanWebpackPlugin(), // 自动构建html文件 new HTMLWebpackPlugin({ // 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 关键字来定义/* 对象包括包含两个部分 属性 方法 */ class Person { /* 直接定义的属性是实例属性,需要通过对象的实例去访问: const per = new Person() per.name 使用static开头的是静态属性 Person.age readonly 开头的属性表示一个只读属性 */ // 定义实例属性 readonly name: string = '孙悟空' // 在属性前使用static关键字可以定义类属性(静态属性) static readonly age: number = 18 // 定义方法 sayHello () { console.log('hello'); }}const per = new Personconsole.log(per);console.log(Person.age);per.sayHello()
6.2 构造函数
class Dog { name: string age: number // 构造函数会在对象创建的时候调用 constructor(name: string, age: number) { // 在实例方法中,this就表示当前的实例 // 在构造函数中当前对象就是新建的哪个对象 // 可以通过this向新建的对象中添加属性 this.name = name this.age = age // console.log(this); } back () { // alert('旺旺旺') // 在方法中可以通过this来表示当前调用方法的对象 console.log(this); }}const dog = new Dog('小黑', 12)const dog2 = new Dog('小白', 23)console.log(dog);console.log(dog2);dog.back()
7 继承
7.1 继承使用 (extends关键字)
(function() { // 定义 Animal 类 class Animal { name: string age: number constructor (name: string, age: number) { this.name = name this.age = age } sayHello() { console.log('动物在叫'); } } /* Dog extends Animal 此时,Animal被称为父类,Dog被称为子类 使用继承后,子类会拥有父类所有的方法和属性 如果在子类中添加了和父类相同的方法,则子类方法会覆盖父类的方法 ,这种叫方法重写 */ // 定义一个狗的类 // 使Dog类继承Animal类 class Dog extends Animal{ run () { console.log(`${this.name}再跑`); } } // 定义一个猫的类 // 使Cat类继承Animal类 class Cat extends Animal{ sayHello() { console.log('喵喵喵'); } } const dog = new Dog('旺财', 5) const cat = new Cat('咪咪', 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 关键字)
(() => { // 描述一个对象类型 type myType = { name: string, age: number } const obj: myType = { name: 'sss', age: 23 } /* 接口用来定义一个类结构, 用来定义一个类中应该包含那些属性和方法 同时接口也可以当成类型声明去使用 */ interface myInterface { name: string, age: number } interface myInterface { gender: string } // 接口可以在定义类的时候去限制类的结构 // 接口中的所有属性都不能有实际的值 // 接口只定义对象的结构,而不考虑实际值 // 在接口中所有方法都是抽象方法 interface myinter { name: string sayHello ():void } /* 定义类时,可以使类去实现一个口接口 实现接口就是使类满足接口的要求 */ class MyClass implements myinter { name: string constructor (name: string) { this.name = name } sayHello () { console.log('大家好' + this.name) } } const myCalss = new MyClass('李四') myCalss.sayHello()})()
11 属性的封装 ( public 、private关键字 )
(() => { // 表示人的类 class Person { // Ts 可以在属性前添加属性的修饰符 /* public 修饰的属性可以在任意位置修改、访问(包括子类) 默认值 private 私有属性,只能在类的内部修改 访问 - 可以通过在类中添加方法使得私有属性可以访问 protected 受保护的,只能到当前类和当前的子类中访问 */ private _name: string; private _age: number; constructor (name: string, age: number) { this._name = name this._age = age } // 定义方法,用来获取name属性 getName () { return this._name } // 定义一个方法用来设置name属性 setName (value: string) { this._name = value } getAge () { return this._age } setAge (value: number) { // 判断年龄是否合法 if (value >= 0) { this._age = value } } // TS 中设置getter方法的方式 get name () { return this._name } set name (value: string) { this._name = value } get age () { return this._age } set age (value: number) { if (value < 0) { return } this._age = value } } const preson = new Person('孙悟空', 23) /* 现在属性是在对象中设置的,属性可以任意修改 属性可以任意修改将会导致对象中的数据变得非常不安全 */ // preson.setName('租八戒') // preson.setAge(-33) preson.name = '租八戒' preson.age = -3 console.log(preson); // _name: "租八戒", _age: 23})()
12 泛型
// function fn(a: number):number {// return a// }/* 在定义函数或是类时,如果遇到类型不明确就可以使用泛型 */ function fn <T> (a: T): T { return a} // 可以直接调用具有泛型的函数fn(10) // 不指定泛型,TS可以自动对类型进行推断fn<string>('hello') // 指定泛型function fn2 <T, K> (a: T, b: K):T { console.log(b) return a}fn2 (123, 'hello')interface Inter { length: number}// T extends Inter 表示泛型 T 必须是 Inter 实现类(子类)function fn3<T extends Inter> (a: T):number { return a.length}fn3('123')fn3({length: 232})class MyClass<T> { name: T constructor (name: T) { this.name = name }}const mc = new MyClass<string>('询')
14 命名空间 (namespace)
namespce A { interface Anmal { name: string; eat():viod } export class Dog implemnts Anmal { name: string; constructor (theName: string) { this.name = theName } eat () { console.log(${this.name} 吃狗粮) } }}namespce B { interface Anmal { name: string; eat():viod } export class Dog implemnts Anmal { name: string; constructor (theName: string) { this.name = theName } eat () { console.log(${this.name} 吃狗粮) } }}var d = new A.Dog('张三')d.eat()var f = new B.Dog('李四')f.eat()
15 装饰器
装饰器是一种特殊的声明,它能够被附加到类声明,方法,属性,或则参数上,可以修饰行为
常见装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器
装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)
类装饰器:在类型声明前被声明,类装饰器应用于类构造函数,可用来监视,修改或替换类定义,传入一个参数
// 类装饰器function logClass(params: any) { console.log(params); // params 就是当前类 params.prototype.apiUrl = '动态扩展的属性' params.prototype.run = function () { console.log('我是一个run方法'); }}@logClassclass HttpClient { constructor() { } getData () { }}var http:any = new HttpClient()console.log(http.apiUrl);http.run()
类装饰器工厂:
function logClass(params: string) { return function(target: any) { console.log(target); console.log(params); target.prototype.apiUrl = params }}@logClass('http://www.yes.com')class HttpClient { constructor() { } getData () { }}var http:any = new HttpClient()console.log(http.apiUrl);
属性装饰器:
// 属性装饰器function logProperty(params: any) { return function(target: any, attr: any) { console.log(target); console.log(attr); target[attr] = params }}class HttpClient { @logProperty('http://weqweqwe.com') public url:any | undefined constructor() { } getData () { console.log(this.url); }}var http:any = new HttpClient()http.getData()
作者:Cola_Mr
链接:https://www.jianshu.com/p/6998c49fc295