# javascript
**Repository Path**: boss_Z/javascript
## Basic Information
- **Project Name**: javascript
- **Description**: 笔记
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-08-26
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## JavaScript
### js的引入方式
* 内部引入: 就是通过标签来引入js代码
* 外部引入:
### 暂且需要记住的测试方法
* ``` document.write(exp) ``` 在页面中输入""里面的内容
* alert(exp) 在警告框里弹出""里面的内容
* confirm(exp) 返回true或false
* console.log(exp) 在控制台输入""里面的内容
### 标识符:是变量名,对象的属性名,和函数名的命名规则。
* 可以出现英文字母,数字,$,_;
* 数字不能作为第一个字符。
### 变量:数据(值)的容器;
```js
var 变量名 //有了一个变量
变量名 = 值 //为变量赋值
变量名 //使用变量
var 变量名 = 值 //声明变量并赋值
```
### 关键字:系统级的标识符。
### 表达式与返回值:表达式就是一段有返值(计算回结果)的代码段,或者是说有返回值的都是表达式。
### 运算符:将简单表达式组合成复杂表达式的方法。
### 数据类型
* Number(数字):1,2,3,-1,0,100,NaN,Infinity,-Infinity
* String(字符串):"王大伟","abc","王abc","1","true",""
* Boolean(布尔值):true false
* undefined undefined
* Object(对象):{属性名:属性值,属性名:属性值}
* Function(函数)
```javascript
//返回数字的整数部分
parseInt(exp)
parseFloat(exp)
//四舍五入
Math.round(3.5)
```
### 数据类型的转换
* Number(exp)
* String类型转Number除了纯数字以外其他情况全部为NaN
* Boolean类型转Number,true为1,false为0
* String(exp)
* 全部以字面量的形式进行转换
* Boolean(exp)
* Number类型转换布尔值,除了0和NaN以外其余全为true。
* String类型转Boolean,除了空字符串以外全为true
* undefined为false
* Object 所有情况全为true
```javascript
元素的id名.onclick = function(){
}
元素的id名.value
元素的id名.innerHTML = 新值
```
### 表达式的副作用:因为一句话的存在与否,会对整个JS上下文执行环境造成一定影响的话,就叫做有副作用的表达式。
### 自增与自减
```
++或--自增/自减运算符拥有表达式的返回值和副作用两种功能。
如果放在操作数后,则先返回再自增;如果放在操作数前则先自增再返回。
```
### 逻辑与和逻辑或
```
&&和||一定会返回运算符两端任意一端的操作数,具体返回哪一个要看最左端操作数强制转换为Boolean值后的结果。
```
### 语句
#### 条件语句
``` javascript
if(exp){
语句1
}
else{
语句2
}
switch (变量){
case 常量1:{
代码..
...
..
break;
}
case 常量2:{
代码..
...
..
break;
}
case 常量3:{
代码..
...
..
break;
}
default:{
代码..
...
..
}
}
条件?分支1:分支2
```
#### 循环语句
``` javascript
for(var i = 0; i < 数字;i++){
循环体
}
while(exp){
循环体
}
do{
循环体
}
while(exp)
break 跳出整个循环
continue 跳出本次循环
```
### function函数: 就是一段可以被高度复用的代码段
```javascript
声明函数
function 函数名(形参,形参,形参...){
//函数体
...
...
...
}
执行函数
函数名(实参,实参,实参....)
```
#### arguments参数对象:一个函数的所有参数的集合,它是一个类数组,它拥有数组的下标和.length特性。
```javascript
//返回实参的个数
arguments.length
//提取出某一个数据
arguments[数字]
```
#### return
* 如果这个函数它没有return语句那么调用函数语句的返回值一律为undefined。
* 影响调用函数表达式的返回值
* 当程序运行到return语句时会终止程序运行本函数
### JS的报错机制
* 试图调用一个本不存在的函数或对象中不存在的方法,程序会报错,xxx is not a function
* 试图使用一个本不存在的变量,程序会报错,xxx is not defined
* 试图查找对象中不存在的属性时,程序不会报错,返回undefined。
### 函数的本身(函数的引用):
```javascript
function add(a,b){
alert(1)
return a + b;
}
add -> add函数的引用
(function(){}) -> 本函数的引用
```
### IIFE自调用函数
```javascript
(function(a,b){
alert(1)
return a + b;
})(2,5)
```
### 变量作用域:在js中只有函数作用域的概念,没有块级作用域的概念。
### 局部变量:在函数里面正常声明的变量,该变量只能在函数体内部或内部函数中被访问到。
### 全局变量:在函数体外部声明的变量,或者是在函数体内省略掉var关键字声明的变量,该变量可以在任意位置被访问到。
### 在某个局部作用域下当局部变量域全局变量发生冲突时,在该作用域中以局部变量为主。
### 变量提升:当执行某个函数时,js解释器会遍历整个函数的局部变量,并在正式执行函数里面的代码前声明这些变量但不赋值,此时这些变量里面的值为undefined。
### 数组:数据的有序集合。
```javascript
//声明一个空数组
[]
[1,5,6,3,4,1,2,5]
// 使用数组下标的形式提取元素
Array[下标]
// 替换/追加
Array[下标] = "睡神"
//返回数组的长度
Array.length
//枚举数组/循环数组
for(var i = 0; i < array.length;i++){
console.log(array[i])
}
```
#### 对象:属性的无序集合。
```javascript
//声明空对象
{}
//声明并赋值
var wangdawei = {
name:"王大伟",
age:18,
sex:"male",
height:187,
weight:130,
sayName:function(){
alert("王大伟")
}
}
// 获取对象中某个属性的属性值
Object.属性名
Object[属性名]
// 对象的修改和设置
Object.属性名 = 新值
Object[属性名] = 新值
// 对象属性的删除
delete Object.属性名
// 对象属性的检测
属性名 in 属性值 -> Boolean
// 对象的枚举/循环
for(var i in obj){
console.log(obj[i])
}
```
### DOM(文档对象模型)
#### document
* getElementById("id") 返回页面中与id值相一致的Node节点
* getElementsByTagName("标签名") 返回的不是Node,是NodeList
* getElementsByClassName("类名") 返回值NodeList
* querySelectorAll("css选择器") NodeList
* createElement("标签名") 返回一个新创建的Node节点
#### Node:特殊的Object,这种对象代表页面中某一个元素,该对象下有很多内置的属性和方法。
* innerHTML 设置/修改页面中元素开始标签与结束标签之间的内容
* className 修改/获取元素的class
* getElementsByTagName() 通过标签名获取元素返回NodeList
* setAttribute(属性名,属性值) 设置元素的行内属性(可以是自定义属性)
* getAttribute(属性名) 获取某个行内属性的属性值
* nodeType 返回节点类型(1代表元素,3代表文本节点,8代表注释节点,9document)
* parentNode 返回父级元素
* nextElementSibling 下一个紧邻的兄弟元素节点
* previousElementSibling 上一个紧邻的兄弟元素节点
* childNodes 返回元素的所有严格意义上的子节点(包含文本节点和注释节点)
* children 返回所有严格意义上的子元素节点
* cloneNode(true) 克隆并返回元素的副本
* appendChild(Node) 会将参数Node节点插入到调用方法的Node节点的结束标签之前
* insertBefore(node1,node2) 会将node1节点插入到node2节点之前
* removeChild(node) 删除掉参数节点
* firstElementChild 第一个子元素
* lastElementChild 最后一个子元素
* nodeName 返回元素标签名(大写)
* style 设置/获取元素的内联样式
* checked 设置/获取 单选按钮和多选按钮的选中状态 返回Boolean
```javascript
node.style.fontSize = "12px";
```
* value 返回文本框/密码框的里面的输入的值
```javascript
getComputedStyle(node,false).css属性
```
#### NodeList:包含了若干的Node节点的类数组,NodeList的方法和属性基本没有,它和Node节点是互相独立。
## this关键字的出现场景
* 出现在事件处理函数里,返回触发该事件的Node节点元素本身
* 出现在全局作用域(window)或是一般函数内部,指向的就是window对象。
* 出现在对象的方法里,指向的就是该对象。
### Math对象
* PI 返回圆周率
* abs() 返回绝对值
* ceil() 向上取整
* floor() 向下取整
* round() 四舍五入
* max() 返回最大值
* min() 返回最小值
* random() 返回0~1之间的伪随机数
### Array对象的全局方法
* shift() //删掉第一个
* pop() //删掉最后一个
* push() //向数组尾端插入一个元素
* unshift() //向数组前端插入一个元素
* concat(Array,Array,Array...) 数组拼接
* reverse() // 反转数组成员的顺序,修改原数组!
* slice(start,end) //切割数组
* splice(index,howmany,replace) 替换/删除 ,修改原数组!
* toString() 包含所有数组成员的字符串,每个成员之间以,分割。
* join("分隔符") 包含所有数组成员的字符串,每个成员之间默认以,分割,如果传递参数,则以参数字符分隔。
```javascript
// 从数组中扣下来第三个元素
arr.splice(3,1)
// 从数组中挤一个元素进去
// arr.splice(2,0,"哈哈")
```
### String对象的全局方法
* concat(str,str,str...) 字符串拼接
* indexOf(str) 检索参数字符串中在调用方法的字符串里首次出现的位置,如果没找到则返回-1
* lastIndexOf(str) 同上,但是是从后往前寻找,但返回的结果依旧是顺序的下标。
* charAt(index) 根据下标寻找字符串
* replace(被替换的字符串,替换之后的字符串)
```javascript
// console.log(str1.replace("d","m")) // 惰性匹配 只修改一个字符
// console.log(str1.replace(/d/g,"m")) // 全局匹配 只要符合要求就全改
```
* slice(start,end) 切割字符串,注意:结果包含开始位不包含结束位。
* split("分隔符") 以参数分割符为界限将原字符串切割成包含所有字符串的数组
* substr(start,howmany) 切割字符串
* substring(start,end) 切割字符串,包含开始位不包含结束位。
* toLowerCase() 转为小写
* toUpperCase() 转为大写
#### 所有的使用new执行的构造函数的返回值是都是一个对象。
### Date对象
1.获取系统当前时间
```javascript
var date = new Date() 返回一个对象,里面存储的执行这个语句时具体的时间。包括了年月日时分秒星期几...
date.getFullYear() 返回日期对象里面年份
date.getMonth() + 1 返回月份
date.getDate() 返回日
date.getHours() 返回小时数
date.getMinutes() 返回分钟数
date.getSeconds() 返回秒数
date.getDay() 返回星期几 0-6 星期日返回0
date.getTime() 返回时间戳,1970年1月1日00:00:00到日期对象所代表的时间中间所经过的毫秒数
```
2.将当前时间转换为字符串
```javascript
function parseNowDate(){
var date = new Date();
var result = "";
result = date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日" + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes():date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" +date.getSeconds():date.getSeconds());
return result;
}
```
3.将Date对象处理成字符串(拥有默认当前时间的)
```javascript
function parseDate(date){
var date = date || new Date();
var result = "";
result = date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日" + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes():date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" +date.getSeconds():date.getSeconds());
return result;
}
var date = new Date("1919-10-1 08:00:00")
console.log(parseDate())
```
4.获取目标时间
```javascript
var date = new Date("2020-10-1")
var date = new Date("2020-10-1 08:00:00")
```
5.设置目标时间
```javascript
var date = new Date()
date.setFullYear() 设置日期对象里面年份
date.setMonth() 设置月份
date.setDate() 设置日
date.setHours() 设置小时数
date.setMinutes() 设置分钟数
date.setSeconds() 设置秒数
```
6.获取两个日期对象之间间隔多少时多少分多少秒
```javascript
function getDateRange(target){
var now = new Date();
var n = parseInt((Math.abs(now.getTime() - target.getTime())) / 1000);
var hours = Math.floor(n / 3600) < 10 ? "0" + Math.floor(n / 3600) : Math.floor(n / 3600)
var minutes = Math.floor(n % 3600 / 60) < 10 ? "0" + Math.floor(n % 3600 / 60) : Math.floor(n % 3600 / 60)
var seconds = Math.floor(n % 60) < 10 ? "0" + Math.floor(n % 60): Math.floor(n % 60);
return hours + ":" + minutes + ":" + seconds
}
var target = new Date("2020-7-5 00:00:00")
var target2 = new Date("2020-7-15 00:00:00")
console.log(getDateRange(target))
console.log(getDateRange(target2))
```
### 计时器
* setInterval(function,number):每过number毫秒后会执行一次function
* setTimeout(function,number):当过了number毫秒后执行function
```javascript
setTimeout(function(){
alert(1)
},2000)
```
* clearInterval(计时器ID)
```javascript
var autoPlay = sertInterval(function(){
},1000)
clearInterval(autoPlay)
```
* clearTimeout(计时器ID)
```javascript
var autoPlay = setTimeout(function(){
},1000)
clearTimeout(autoPlay)
```
### BOM:内置对象window
#### window对象下所有的属性和方法都是可以省掉window.的
* alert()
* confirm()
* parseInt()
* setInterval()
* setTimeout()
* clearInterval()
* clearTimeout()
#### window.location属性:代表当前游览器的URL地址
```javascript
window.location.href // 整个url地址
window.location.href = "xxx" 页面跳转
localtion.reload() 刷新页面
```
#### window.navigator:代表和浏览器相关的信息
```javascript
navigator.userAgent 返回浏览器信息(该信息具有误导性)
navigator.appName 获取当前浏览器的名称
navigator.appVersion 获取当前浏览器版本
navigator.platform 获取操作系统信息
```
```javascript
关闭页面
window.close()
打开一个新页面
window.open("url")
```
### window.history
```javascript
前进
history.forwrad()
history.go(1)
后退
history.back();
history.go(-1)
```
```javascript
获取可视区域
document.documentElement.clientWidth
document.documentElement.clientHeight
获取/设置滚动距离
document.documentElement.scrollTop
document.documentElement.scrollLeft
window.onload 事件
window.onload = function(){
当页面加载完毕之后执行事件处理函数
}
window.onscroll事件
window.onscroll = function(){
当页面滚动条发生移动或滚动时执行事件处理函数
}
```
### 递归:在函数体内部调用自身
```javascript
function age4(){
return 10;
}
function age3(){
return age4() + 2
}
function age2(){
return age3() + 2
}
function age1(){
return age2() + 2
}
n:一共有几个小朋友
function age(n){
if(n === 1){
return 10;
}
return age(n - 1) + 2;
}
console.log(age(4))age(3)age(2) age(1)
function jiecheng(n){
var m = 1;
for(var i = 1; i <= n;i++){
m *= i;
}
return m;
}
console.log(jiecheng(14))
function jiecheng(n){
if(n === 1){
return 1;
}
return n * jiecheng(n - 1)
}
console.log(jiecheng(9))
```
### 引用类型和原始类型:引用类型包含对象(数组,function),其余的数据类型都为原始类型。基本类型赋值是值的复制,而引用类型是引用(指针)的复制。 引用类型的比较是引用的比较而非和原始类型值得比较
```javascript
var wangdawei = {
name:"王大伟",
age:18
}
var chenyan = wangdawei;
chenyan.name = "陈炎"
wangdawei.age = 20;
chenyan.age = 20;
console.log(wangdawei)
console.log(chenyan)
var arr1 = [1,5,6,3]
var arr2 = arr1;
arr2[0] = 0;
console.log(arr1)
```
### 事件:给一个元素监听某个事情的发生。
#### 事件绑定写法
```javascript
我是div里面的内容
```
```javascript
第二种绑定事件的方式
Node.事件名 = function(){
// 事件处理函数(事件句柄)
}
window.事件名 = function(){
}
document.事件名 = function(){
}
```
```javascript
第三种绑定事件的方式(事件监听)
Node.addEventListener("去on的事件名",function(){
},true/false)
```
#### 事件类型
##### 鼠标
* onclick 鼠标单击
* onmouseover 鼠标经过
* onmouseout 鼠标离开
* onmouseenter 鼠标进入
* onmouseleave 鼠标离开
* onmousemove 鼠标移动
* onmousedown 当鼠标按下时
* onmouseup 当鼠标抬起时
#### 键盘
* onkeydown 当键盘某个按键被按下的时候;如果想要获取一个文本框的某个值的话,就不要使用onkeydown,因为太早了。
* onkeyup 当键盘某个按键被抬起的时候
* onkeypress 过滤掉功能键版本的onkeydown
#### 事件对象:当用户触发事件的时候,浏览器给执行的那个函数(事件处理函数)传递的实参,里面包含着触发事件时浏览器所记录的信息。
```javascript
node.事件名 = function(e){
e //事件对象
}
```
#### 鼠标事件对象中的属性
* clientX
* clientY 相对于浏览器
* offsetX
* offsetY 相对于元素
* screenX
* screenY 相对于屏幕
* which 哪一个鼠标按键被按下了 返回1左键 2滚轮按下 3右键
* target 返回当前触发事件浏览器事件传播机制流程中目标阶段的节点,也代表鼠标所指向的最深层次的元素。
#### 键盘事件的事件对象
* keyCode 返回键码,根据键盘来判断用户按的是哪个按键.
* ctrlKey 触发事件时,ctrl键有没有被按下去,Boolean
* AltKey
* shiftKey
### 作业
#### 鼠标跟随一串效果
#### 记录移动轨迹
#### 模拟聊天框
#### 扩展:虚拟键盘
#### 事件监听:多个监听事件不会相互覆盖,而是叠加。
```javascript
事件监听
Node.addEventListener("去on的事件名",function(){
},true/false)
```
#### 事件的传播机制:当用户在页面中触发了某个事件,浏览器会先进入捕获阶段,从外向内依次寻找元素,然后再进入第二阶段从内向外的冒泡阶段。所有的主流浏览器绑定事件后,默认事件是在冒泡阶段触发,如果想要修改这一行为,则必须使用事件监听的绑定方式,最且最后一个参数传入true则该事件变为捕获阶段。
#### 事件委托:将子元素的事件委托给它们的祖先级元素来办,然后通过事件对象的target属性来代替已经混乱的this使用。
##### 事件委托的优势:
* 解决动态元素无法绑定事件的问题
* 在极端情况下可以节省客户端性能
##### 劣势:
* 造成this指向混乱
#### 阻止浏览器的默认行为 event.preventDefault() || retrun false;
#### 阻止事件冒泡 stoppropagation()
#### 特殊的事件
* 表单元素.onblur:当某个表单元素失去焦点时
* 表单元素.onfocus: 当某个表单元素获得焦点时
* window.oncontextmenu: 当用户呼出浏览器菜单时
### 作业:
#### 可编辑的表格
#### 自定义右键菜单
#### 含有边缘碰撞检测拖拽
#### 运动原理
##### 渐隐渐显的运动
```html
```
##### 移动的运动
```html
```
#### 高级运动原理
##### 非匀速运动
##### 运动的回调
### 返回元素相对于它的父级元素的偏移量,这个属性是只读属性。
* offsetLeft
* offsetTop
### 返回元素在页面中所占据的位置(盒模型解析的尺寸),这个属性是只读属性。
* offsetWidth
* offsetHeight
#### 作业
* 土豆底部导航(运动的回调)
* 导航动画(非匀速动画)
##### 下拉选择菜单独有的事件:onchange
```javascript
// 只有当下拉选择菜单中的值发生改变的时候会触发onchange事件
下拉选择菜单Node.onchange = function(){
// this.value所返回的就是当前所选中的选择项option标签value属性的属性值
this.value
}
```
#### 周末作业
##### 1.贪吃蛇(移动,键盘控制移动,得分,死亡检测)
##### 2.展开菜单
##### 3.tab选项卡
##### 4.数码时钟
##### 5.完善顶部导航(非匀速动画)& 土豆底部导航(非匀速回调动画)
#### ES6特性1
##### 声明变量
```javascript
let 声明变量的
const 声明常量的(声明了之后就不可修改)
以上两者和var关键的区别:
1.不可重复声明
2.拥有了更加标准化的块级作用域的概念。
3.不再有奇奇怪怪的变量提升机制了。
```
##### 模板字符串
```javascript
console.log("现在是: " + hours + ":" + minutes + ":" + seconds);
console.log(`现在是: ${hours}:${minutes}:${seconds}`)
```
#### 箭头函数:影响函数体内部的this指向,箭头函数中的this会穿透本层函数指向上一层作用域中的this。
```javascript
var fn = function (){
alert(1)
}
var fn = ()=> {
alert(1)
}
var add = function(num1){
alert(num1)
}
var add = (num1)=>{
return (num1)
}
//如果只有一个形参,那么可以省略()
var add = num1 => {
return (num1)
}
//如果函数体内的语句只有一条,那么可以省略{}
var add = num1 => num1
add(10)
document.getElementById("div1").onclick = ()=>{
setInterval(()=>{
console.log(this)
},1000)
}
```
#### 解构赋值
```javascript
var arr = [10,20]
let [a,b,c] = arr;
var obj = {
name:"王大伟",
age:18,
sex:"男"
}
let {name,age,sex} = obj;
console.log(sex)
```
#### 展开数组
```
let arr = [1,5,6,3]
// arr2拥有了所有arr数组中的成员
var arr2 = ["new",...arr]
console.log(arr2)
```
#### 数组的新方法
* indexOf
```
// 接收两个参数:要查找的项,和(可选的)表示查找起点的位置。
// 返回值是你要查找元素的下标
// console.log(arr.indexOf(1,3))
```
* forEach
```javascript
// 接收一个参数:function
// 该函数拥有三个参数function(item,index,array)
// item依次代表数组中每一个成员
// index依次代表数组中的下标
// array永远都代表数组本身
arr.forEach(function(item,index,array){
console.log("第" + index + "个成员是:" + item)
})
var spans = document.getElementsByTagName("span");
spans.forEach(function(item,indedx,array){
// 报错,因为NodeList不是真实的数组,不存在数组的全局方法
console.log(item)
})
```
* map
```javascript
// 会遍历当前数组,然后调用参数中的方法,返回当前方法的返回值。
var arr = arr.map(function(item,index,array){
return item * 2
})
```
* filter
```javascript
会遍历当前数组,然后调用参数中的方法,根据参数函数的返回值是true还是false来代表整个方法的返回值长度和内容
var arr = [1,5,6,3,4,1,2,5];
arr.filter(function(item,index){
return item > 3;
})
```
#### 构造函数与原型对象prototype
##### 构造函数就是生产对象的函数
##### 每一个构造函数都拥有一个prototype属性,该属性指向原型对象.
##### 每一个原型对象都有用一个constructor属性,该属性返回该原型对象的构造函数。
##### 每一个实例化对象都拥有一个__proto__属性,该属性会返回该实例化对象的构造函数的原型对象。
```javascript
function person(name,age,sex){
let o = {}
o.name = name;
o.age = age;
o.sex = sex;
o.sayName = function(){
alert(this.name)
}
return o;
}
let wdw = person("王大伟",18,"男");
严谨的构造函数
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Funtion.prototype -> Object 原型对象
Person.prototype.type = "灵长类";
Person.prototype.sayName = function(){
alert(this.name)
}
let wdw = new Person("王大伟",18,"男");
let cy = new Person("陈炎",27,"男");
let htn = new Person("贺桃娜",18,"女");
console.log(Person.prototype.constructor === Person)
console.log(wdw.__proto__ === Person.prototype)
console.log(wdw.constructor)
let str1 = "heihei";
let str2 = new String("haha");
console.log(str1.__proto__)
console.log(String.prototype)
String.prototype.indexOf = function(){
alert(1)
return "嘿嘿";
}
String.prototype.wangdawei = function(){
var result = "";
for(var i = this.length - 1; i >= 0;i--){
result = result + this[i]
}
return result;
}
var mm = "abcdefg";
console.log(mm.wangdawei())
```
####阶段中案例
##### 电商评分功能
##### 购物车操作功能
##### 轮播图功能
##### 放大镜功能
#### 文件走真实的网络协议
```javascript
http://10.35.101.90
http://www.baidu.com
```
#### 怎么让本机的文件可以通过网络协议被访问到
* 通过web Server软件来实现 IIS,Apache,ng
* 通过NodeJS 的HTTP或者EXPRESS第三模块实现
#### 网络IP分为内网IP和公网IP
#### 将域名转换为IP地址的过程:DNS解析
#### Web Server的底层原理就是打开本机的某一个端口号(HTTP协议一般都占用80端口,HTTPS一般都占用443端口),然后其他电脑就可以通过IP地址或域名的方式访问你的这台电脑,然后由你的这台电脑向访问者提供一个文件。
##### 每一台电脑都默认拥有65535个端口
## Ajax:HTTP脚本化,就是利用JavaScript代码来控制HTTP请求。
```javascript
//1.实例化XMLHttpRequest对象
let http = new XMLHttpRequest();
//2.规划一个HTTP请求http.open(method,url,同步/异步)
http.open("get","http://10.35.161.90/test.txt",true)
//3.发送请求
http.send()
// 4.接收来自服务器端返回的内容
http.onreadystatechange = function(){
if(http.readyState === 4){
//接收到服务器端返回结果后需要处理的逻辑
http.responseText
}
}
```
### URL请求参数:
```
http://10.35.161.90/test.php?name=wangdawei&age=18&sex=1
语法结构:key=value&key=value&key=value
```
#### PHP
```php
//固定模板
//声明变量
$message = "success!!!";
//输出
echo 表达式;
//声明数组
$arr = array("成员1","成员2","成员3")
//获取数组中的成员
$arr[0]
//PHP获取随机整数
//rand(min,max)
//获取来自前端的请求参数
$_GET["参数名"] -> 参数名所对应的参数值
```
#### MYSQL
##### 其他的数据库:sqlserver,Oracle,mysql,MongoDB,Microsoft Access
##### 操作数据库的语言:SQL语句
##### 常见的数据库操作:增删查改,排序
#### 数据库的结构:库>n个表>n个字段>数据
#### 每一个表都相当于是一个Excel表格,每个字段都相当于是表格中的某一个列。
#### 设计表的原则
1.每个表都要有且仅有一个ID字段,并且该字段是唯一的,并且该字段应为整个表的主键。
#### 暂且需要记住的数据类型
* int 整数
* varchar 字符串
* float 小数
### SQL语句
```mysql
// 查找所有数据的所有字段
SELECT * FROM 表名
// 查找所有数据中的姓名字段
SELECT name FROM 表名
// 根据某个条件来查询数据
SELECT * FROM 表名 WHERE 字段名="某值"
// 根据某个条件来查询数据
SELECT * FROM 表名 WHERE 字段名="某值" AND 字段名="某值"
SELECT * FROM 表名 WHERE 字段名="某值" OR 字段名="某值"
// 查询并排序
SELECT ......... ORDER BY 字段名
// 插入语句
INSERT INTO 表名 (字段名,字段名,字段名..) VALUES ("值1","值2","值3",....)
// 删除整个表
DELETE FROM 表名 WHERE 字段名="某值"
//修改
UPDATE 表名称 SET 列名=新值 WHERE 列名=某值
```
### JSON:一种前后端交换数据的通用格式,以js语法中对象套数组或数组套对象格式为规则。但属性名必须用双引号包起来,并且不允许出现注释。
* JSON.parse(JSON字符串) -> JSON对象
* JSON.stringify(JSON对象) -> JSON字符串
### 本地存储:浏览器允许网站开发者在用户的硬盘上写一小部分数据。
#### cookie
##### document.cookie多次声明不会覆盖
```javascript
// 设置一条cookie
document.cookie = "key=value;expires=date对象";
let cookie = {
// 获取cookie
get:function(key){
let result = {};
let arr = document.cookie.split(";");
arr.forEach((item)=>{
result[item.split("=")[0].replace(" ","")] = item.split("=")[1];
})
if(!key){
return result;
}
else{
return result[key];
}
},
// 设置cookie
set:function(key,value,date){
let d;
if(typeof date === "number"){
d = new Date();
d.setDate(d.getDate() + 30)
}
if(typeof date === "object"){
d = date;
}
document.cookie = `${key}=${value};expires=${d}`;
},
// 删除 cookie
remove:function(key){
let d = new Date("1970-1-1");
document.cookie = `${key}=0;expires=${d}`;
}
}
```
#### localStorage
```javascript
// 设置
setItem(key,value);
getItem(key);
// 删除
removeItem(key,value);
// 清空
clear()
```
#### sessionStorage
```javascript
sessionStorage.setItem("key", "value")
sessionStorage.getItem("key")
sessionStorage.removeItem("key")
sessionStorage.clear()
```
#### cookie和localStorage以及session的不同点
* 1.cookie是可以灵活设置数据的生命周期,但localStorage的数据生命周期是永久性存储。
* 2.localStorage IE8以上才兼容,而cookie不存在兼容性问题。
* 3.cookie存读不方便,需要字符串处理,而localStorage不用。
* 4.session的生命周期是在会话时,关掉浏览器自动销毁。
#### Ajax POST请求
#### GET和POST请求代码的不同点:
* 1.open()方法的第一个参数改成POST
* 2.如果这次请求是含有参数的请求,那么请求参数要从URL地址栏处转移到send()方法中以字符串参数的形式存在
* 3.如果这次请求是含有参数的请求,那么需要在发送请求之前设置请求头。
#### GET和POST底层的不同点
* 1.GET的请求的请求参数是走URL地址栏的,而POST是装到HTTP请求内部的。
* 2.敏感数据会用POST请求,常规数据是用GET请求(前端说的不算)。
* 3.请求参数的长度GET是有限制的,而POST一般来说是无限制的。
```javascript
let http = new XMLHttpRequest();
http.open("POST", "ajax_test.asp", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send("fname=Bill&lname=Gates");
```
#### 跨域与同源组策略
```javascript
//跨域
http://www.baidu.com
https://www.baidu.com/xxx
//同域
http://192.168.0.1/index.html
https://192.168.0.1/aaa/xxx
//跨域
http://www.163.com/index.html
http://music.163.com/sss
//跨域
http://127.0.0.1/index.html
http://127.0.0.1:8080/sss
//跨域
http://10.35.161.90/index.html
http://127.0.0.1/sss
```
#### jsonp:解决跨域问题的一种方法,但是这不是一种标准技术.
```javascript
//回调函数:在后端返回数据之后自动执行
function 回调函数函数名(data){
//这里的形参就代表后端返回的数据
console.log(data)
}
// 通过JSONP请求方式获取游戏数据
let script = document.createElement("script");
script.src = "http://49.235.82.222:8080/recommendGame?callback=回调函数函数名"
let head = $("head");
head.appendChild(script)
```
#### JSONP的工作机制:前端利用一个script标签向后端发送一次get请求,后端接收到请求之后会向前端返回一段执行函数的JS代码段,并且将要返回给前端的数据通过参数的形式传递,该函数的函数名前端通过callback请求参数发送给后端,前端在早些时候已经声明好要被调用的回调函数了,当前端接收到来自后端返回的代码段时,该回调函数会被自动执行,并且此时的形参就代表了后端要返回的数据。
#### 作业:跨域请求steam数据
### jQuery:类库(工具箱):宗旨是write less do more,功能:DOM操作,DOM获取,动画,数据交互(ajax),链式调用。
#### 版本
* 1.xx.xx IE6都支持
* 2...x.. IE8支持
* 3.xx.xx IE10支持
#### 文件类型
xxxx.min.js 压缩版,生产版。(无注释和换行缩进)
xxxx.js 开发版。
#### jQuery的核心方法
```javascript
//1.在页面中查找与css选择器相匹配的元素,返回相匹配的jQuery对象
$("css选择器")
//2.将源生JS节点(Node,Nodelist)转换为jQuery对象
$(Node||NodeList)
//3.类似于window.onload事件
$(function(){
// 当页面加载完毕之后会执行这里的代码
})
//4.创建一个jQuery对象
$("HTML代码段")
比如:$("哈喽哇
")
```
### jQuery对象到底是啥?!!!
* 是一个类数组。
* 所有数组成员都是原生JS节点。
* jQuery和原生js节点的属性和方法互不通用。
### jQuery对象的方法
* html() 获取/修改标签内的内容
* val() 获取/修改value属性的属性值的内容
* addClass() 追加类名
* removeClass() 删除类名
* toggleClass() 删除/追加类名
* hasClass() 检测元素是否含有某个类名 返回Boolean
* attr() 设置/获取元素的自定义属性
```javascript
//设置
jQuery对象.attr(key,value)
//获取
jQuery对象.attr(key)
```
* remove() 删除元素
* append() 将参数元素插入到调用方法的结束标签之前
```javascript
要插入的位置.append(插入的元素)
插入的元素.appendTo(要插入的位置)
```
* before() 将参数元素插入到调用方法的元素之前
* after() 将参数元素插入到调用方法的元素之后
* index() 返回当前jQuery对象相对于其他兄弟元素在父级元素中的下标
* find("css选择器") 从元素内部查找与css选择器相匹配的子孙级元素,返回jQuery对象
* closest("css选择器") 从调用方法元素开始逐层向上寻找组先级元素,直到找到某一个与css选择器相匹配的元素为止停止寻找并返回找到的jQuery对象,结果集一定是一个元素。
* eq(Number) 从jQuery对象结果集中提取出某一个元素,返回结果不是Node节点是jQuery对象。
* clone(true) 克隆节点,返回jQuery对象副本。参数传true代表是否连同模板的事件一起克隆
* show()
* hide()
* toogle()
* fadeIn(Number,function(){})
* fadeOut(Number,function(){})
* fadeToggle(Number,function(){})
* slideDown(Number,function(){})
* slideUp(Number,function(){})
* slideToggle(Number,function(){})
* css() 操作元素的行内属性
```javascript
jQuery对象.css({
height:"300px",
width:500,
marginLeft:50
})
```
* animate(css对象,时间,回调函数) 操作元素的行内属性动画
#### jQuery对象绑定事件
```javascript
jQuery对象.去on的事件名(function(){
// 指的是源生js对象
this
})
```
### 作业
* 滑动版的轮播图
* 游戏列表
* 可编辑的表格
* tab选项卡
* Steam对接数据
### jQuery Ajax
```javascript
$.ajax({
// 请求的地址
url:"http://127.0.0.1/getName.php",
// 请求参数
data:{
name:"a",
age:18,
sex:"男"
},
// 请求方式 GET || POST
method:"POST",
// 接收到后端返回成功之后执行的函数
success:function(data){
console.log(data)
}
})
// jQuery 发送jsonp请求
$.ajax({
// 请求的地址
url:"http://49.235.82.222:8080/recommendGame",
// 规定现在不适用Ajax请求,使用jsonp请求
dataType:"jsonp",
// 请求参数
data:{
id:"123"
},
// 接收到后端返回成功之后执行的函数
success:function(data){
data.forEach(item=>{
let h2 = $(".template").clone(true);
h2.html(item.name).removeClass("template").fadeIn()
})
},
// 请求发送之前
beforeSend:function(){
console.log(1)
}
})
```
#### jQuery尺寸
* width()
* height()
* innerWidth()
* innerHeight()
* outerWidth()
* outerHeight()
#### jQuery对象下的方法
* each() 当不得不循环jQuery对象时,可以使用。
```
liList.each(function(){
$(this).attr("data-index",n++)
})
```
#### 主流的跨域请求的解决方案
* JSONP 需要前端参与
* CORS
* 服务反向代理
#### $.fn.extend
```javascript
// 相当于是jQuery对象的构造函数的原型对象中扩展属性和方法
// 所有的jQuery对象都将拥有扩展之后的方法。
$.fn.extend({
zoom:function(){
// this指向的是调用这个方法的jQuery对象
this.animate({
width:0,
height:0,
opacity:0
})
}
})
$(".wrap").zoom()
$("footer").click(function(){
$(this).zoom()
})
```
#### $.extend:废物,没用,给$对象扩展属性和方法的,一般来说我们很少需要这种场景。
### 正则表达式
#### 什么是正则表达式:描述一种规则或者是一种模式的语法。
```javascript
//字面量
/正则/修饰符
/[0-9]/g
//构造函数的声明方式
new RegExp("正则","修饰符")
```
#### 正则表达式和字符串配合的方法
* search(reg) 类似于indexOf,但是它可以接收正则参数
* match(reg) 接收正则参数,返回与正则相匹配的字符,返回结果是数组。如果没有任何结果返回null
* replace(reg,"") 替换
#### RegExp.test()方法:检测 返回true false
```
RegExp.test(str)
```
#### 量词
```
? 有一次或0次
+ 至少有一次
* 无限次
{1,3} 最少1次,最多3次
{1} 一次
{1,} 最少1次,最多不限
```
#### 元字符:中括号,代表一个范围
```
// 中括号:元字符,代表一类字符
// [0-9],[a-z],[A-Z],[A-z],[0-9a-z]
// 排除
// [^0-9]
// [\dxX] 等价于 (\d | x | X)
```
#### 转义
* \d 匹配数字 等价于 [0-9]
* \w 英文、数字、下划线 (忽略大小写)
* \s 匹配空白字符 (空格,tab制表符,回车换行符)
* \D 小版本的取反
* \W 小版本的取反
* \S 小版本的取反
* . 任意字符
#### 匹配座机号
``` /^(\d{3,4}-)?[1-9]\d{6,7}(-\d{1,5})?$/ ```
#### 身份证
``` \d{15}(\d\d[0-9xX])? ```
#### 匹配手机号
``` /^1[3-9]\d{9,9}$/ ```
#### 邮箱校验
``` /^[A-z0-9]+@[A-z0-9]+\.[A-z]+$/ ```
#### 匹配中文
/^[\u4e00-\u9fa5]+$/
#### 参考网址:https://www.jb51.net/tools/regexsc.htm
#### CMD命令
```cmd
<盘符:> 进入某个盘符
进入某个文件夹
返回上一级
展示该文件夹下所有文件
清屏
以node的执行环境执行某个js文件
```
#### 如何把JS文件扔到NodeJS执行环境下执行
``` 以node的执行环境执行某个js文件 ```
#### nodeJS的执行环境下,没有window内置对象,也没有document的内置对象,多了一个global的内置对象。
#### 模块:一个功能的集合,一般来说一个模块就是会返回一个对象。
```javascript
//引入一个模块,表达式会返回一个对象。
let xxx = require("模块名");
```
##### 内置模块
* HTTP:开放webServer服务,接收来自客户端的请求,也可以向客户端返回数据。
```
let http = require("http");
const port = 789;
let count = 0;
// 规划web服务,并将代表服务的对象返回。
let server = http.createServer(function(request,response){
// 向前端返回数据
response.end(`success^_^,count:${++count}`)
// 在服务器端的控制台输出
console.log(`接收到来自客户端的请求,这是第${count}次请求`)
})
// 正式的开启web服务
console.log(`server is running at ${port}`)
server.listen(port)
```
* URL模块:解析一段请求参数的字符串,将字符串转换为对象
```javascript
let http = require("http");
let url = require("url");
const port = 789;
let count = 0;
// 规划web服务,并将代表服务的对象返回。
let server = http.createServer(function(request,response){
// url模块解析来自前端的请求参数
console.log(url.parse(request.url,true).query)
// 向前端返回数据
// response.end(`success^_^,count:${++count}`)
// 在服务器端的控制台输出
// console.log(`接收到来自客户端的请求,这是第${count}次请求`)
})
```
* fs文件系统:操作服务器磁盘的文件
``` javascript
// let fs = require('fs');
// 写文件
// fs.writeFile(`data/hello.txt`,`${parseInt(Math.random() * 100000)}`,()=>{
// console.log(`第次文件写入完成!`)
// })
// 写文件的同步版
// fs.writeFileSync(`data/hello${i}.txt`,`${parseInt(Math.random() * 100000)}`);
// console.log(`第${i}次文件写入完成!`)
// 读文件
// fs.readFile("data/hello100.txt",(error,data)=>{
// if(error){
// console.log("读取文件失败")
// }
// else{
// console.log(String(data))
// }
// })
// 读文件同步
// console.log(String(fs.readFileSync("data/hello500.txt")))
```
##### 第三方模块:需要下载之后再require()的模块。
##### 下载第三方模块
```cmd
npm install 模块名 --save
npm i 模块名 --save
```
##### express:代替http模块
```
const express = require("express")();
let expressStatic = require("express-static");
// 根据请求的路由来执行不同的回调函数
express.get("/",(request,response)=>{
response.end("吼吼")
})
express.get("/a",(request,response)=>{
response.end("哈哈")
})
express.get("/b",(request,response)=>{
response.end("嘿嘿")
})
// 拦截来自所有前端的静态请求,都去static这个文件里去找寻找文件
server.use(expressStatic(__dirname + '/static'))
express.listen(456)
```
##### mysql:让nodejs有能力与数据库通信
```javascript
var mysql = require('mysql');
var sql = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
sql.connect();
sql.query('SELECT 1 + 1 AS solution', function (error, results) {
if (error){
console.log("error")
}
console.log(results);
});
```
##### ejs:模板引擎:赋予服务器端套数据(将数据循环生成HTML节点)的功能。
```javascript
//读取文件,并且注入数据
ejs.renderFile("文件路径",数据模型{},function(error,result){
})
<%= %> 读取变量返回值展现到页面
<% %> 做流程控制
<%- %> 读取变量返回值展现到页面(如果碰到HTML代码,是解析成标签)
```
#### CSS预处理器
#### LESS引入方式
* 真实网络环境
* 独立的外部css文件
* 引入外部css文件要带/less
```
```
* 先引入css文件再引入less.js
```
@变量名:属性值;
混合:
.item{
width:230px;
border:5px solid #e3e3e3;
margin-right:10px;
float:left;
min-height:300px;
}
.sp{
.item;
margin-right:0px;
}
嵌套
.wrap{
width: 1000px;
overflow: hidden;
margin:50px auto;
li {
width:230px;
border:5px solid #e3e3e3;
margin-right:10px;
float:left;
min-height:300px;
}
.sp{
margin-right:0px;
}
}
```
#### call和apply:call方法用来帮助函数进行调用操作,改变当前执行的这一次函数内部的this指向
```
function fn(a,b){
console.log(a+b)
console.log(this)
}
Function.call()
fn(3,5)
fn.call("王大伟",10,20)
```
#### js的继承问题
##### 继承的定义:A类是B类的父类,B类就要拥有所有A类里的属性和方法。
##### 用call调用构造函数的集成方式
* 子类集成父类的时候无法集成父类原型对象下的下属性和方法
```
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.type = "灵长类";
Person.prototype.sayHello = function(){
alert(this.name)
}
function SuperMan(name,age,sex,skill){
Person.call(this,name,age,sex);
this.skill = skill;
}
SuperMan.prototype.brace = function(){
alert(this.skill)
}
let zhu = new SuperMan("猪猪侠",6,"男","嘤嘤嘤");
zhu.sayHello() // 报错,因为父类的原型对象下的方法子类无法集成
```
##### 构造函数+原型链的继承方式
```
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.type = "灵长类";
Person.prototype.sayHello = function(){
alert(this.name)
}
function SuperMan(name,age,sex,skill){
Person.call(this,name,age,sex);
this.skill = skill;
}
// 直接将父类的原型赋值给子类的原型
// SuperMan.prototype = Person.prototype
SuperMan.prototype = new Person();
// 修正子类的constructor指向问题
SuperMan.prototype.constructor = SuperMan;
SuperMan.prototype.brace = function(){
alert(this.skill)
}
let zhu = new SuperMan("猪猪侠",6,"男","嘤嘤嘤");
let wdw = new Person("王大伟",18,"男");
// zhu.sayHello() // 报错,因为父类的原型对象下的方法子类无法继承
console.log(zhu)
console.log(wdw.constructor)
console.log(zhu.constructor)
```
#### ES6 class的形式
```JavaScript
//声明一个构造函数
class Person{
//私有属性方法
constructor(形参){
this.形参 = 形参
....
}
// 原型方法
方法名(){
}
}
class SuperMan extends Person{
//私有属性方法
constructor(形参){
super(父元素的形参列表)
this.形参 = 形参
....
}
// 原型方法
方法名(){
}
}
```
### call和apply的不同:两个方法都是帮助函数去调用一次,会用第一个参数来代替本次调用函数的this,如果调用的函数需要传递实参,并且调用的方式是call的话那么就可以传递多个参数,从第二个参数开始都会被解析成调用函数的实参。而applay,它有两个参数,第二个参数是个数组,这个数组中的所有成员都代表调用函数时传入的实参。
#### 设计模式
#### 瀑布流
#### git 命令
```
git init 初始化git仓库
git add <文件名> 将某个文件从工作区提交到缓冲区
git status 查看仓库状态
git commit -m "提交注释" 将缓冲区内的文件全部提交到版本库
git checkout -- <文件名> 从版本库或缓冲区提取文件覆盖掉工作区的某个文件
git diff <文件名> 比较差异
git log 查看提交日志
git reset --hard <版本id> 回滚整个工作区到版本库中的某一个版本状态
git reflog 查看操作日志
git add -A 将所有被修改或未被追踪到的文件全部提交到缓冲区
git commit -am "提交注释" 将工作区所有被追踪到的文件越过缓冲区直接向版本库进行提交
git clone <地址> 从远程库拉取项目
git push 从本地库推送到远程库
git pull 从远程库更新项目到本地版本库
ssh-keygen -t rsa -C "你的邮箱" 生成秘钥
```
#### gulp:前端项目构建工具。
特点:
1.基于流
2.基于Nodejs,作为nodejs第三方模块的存在。
#### ES6新语法
```
!!!!!!新增循环方法 for of
在枚举数组时,每次都是枚举出数组的元素而非forin的下标。
// for of 不能像for in 一样枚举对象
// for of 在枚举字符串时,每次都是枚举出字符,而非forin的下标。
字符串新增方法
//去留白
s.trim()
s.trimStart()
s.trimEnd()
// Number全局方法
Number.isInteger() 判断是否是整数
// !!!!函数参数的默认值
function Person(name,sex,ismarryed = true){
this.name = name;
this.sex = sex;
this.ismarryed = ismarryed;
}
Array.(类数组的对象) 返回类数组对象转换为真实数组之后的结果
[].find((item)=>{ 枚举数组成员返回第一个与条件相匹配的数组成员
return 条件
})
展开运算符
let arr = [1,5];
SET数据结构
声明set对象
let setArr = new Set();
添加新成员
setArr.add(10)
删除成员
setArr.delete(10)
检测是否含有成员
setArr.has(10)
删除所有成员
setArr.clear()
枚举set对象
setArr.forEach((item)=>{
item
})
将set对象转换为真实数组
let arr = Array.from(setArr)
set数组去重方法
let arr = [1,5,6,3,4,1,2,5]
arr = Array.from(new Set(arr));
```
#### ES6模块化写法
```
1.子模块中使用 export 关键字来将一个或几个变量暴露给外部(一般只暴露一个对象)
2.在主文件中使用 import {对象名} from 路径 "./文件名"
3.在HTML页面中引入主文件,但是一定要在script上加type="module"属性
4.要在真实网络环境协议下测试。
```
##### gulp各个插件
```
npm i gulp gulp-concat gulp-uglyfly gulp-cleanCss gulp-sass gulp-remame --save
npm i express mysql ejs express-static gulp@2.9.1 gulp-concat gulp-uglyfly gulp-clean-css gulp-sass gulp-remame --save
```
### 闭包:就是在外层函数返回一个内层函数,外层函数中声明局部变量,内层函数操作局部变量。整个声明函数的写法是一种IIFE自调用函数形式,并且向内层函数返回给一个变量。当每次调用该函数时,内层函数被调用,外层函数不会被调用。这种写法能将一个全局变量变成局部变量,并且改变这个变量的唯一途径就是调用内层函数。闭包的写法要慎用因为里面的变量不会被JS的垃圾回收机制所自动销毁。