# 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的垃圾回收机制所自动销毁。