一、JavaScript篇
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() 给元素的事件添加函数
- 格式: 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指向
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' // 设置cookie
alert(document.cookie) // 获取cookie
cookie编码中文
encodeURIComponent 将中文编译成对应的字符
decodeURIComponent 将对应的字符编译成中文
document.cookie = 'username=xxx' + encodeURIComponent("钢铁侠") // 设置cookie
alert(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); // true
console.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
- 鼠标事件: 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() {
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 = 3000
const TYPE_ENTER = 0
const TYPE_LEAVE = 1
const 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 = true
c = '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 Person
console.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
}
// 定义一个接口属性为任意值,但属性值为置顶类型,如:{ a: [ { name: 'sd', age: 23 } ], b: [ { name: 'test', age: 32 } ] }
interface anyInterface {
[key: string]: myInterface[]
}
// 接口可以在定义类的时候去限制类的结构
// 接口中的所有属性都不能有实际的值
// 接口只定义对象的结构,而不考虑实际值
// 在接口中所有方法都是抽象方法
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方法');
}
}
@logClass
class 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()