# zsnote **Repository Path**: zhong_dong/zsnote ## Basic Information - **Project Name**: zsnote - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-02-16 - **Last Updated**: 2023-02-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## JavaScript * 简介:JavaScript是在浏览器中解释运行的**脚本语言**,用来给HTML网页**增加动态功能**。 * JS的组成 - ECMAScript - DOM - BOM ### JS的引入方式 * 内部引入 * 外部引入 * 行内引入 ##### 如果哪一个script标签用于引入外部js文件了,那么浏览器会忽略掉该标签内部所有的js代码(如果有的话) #### 暂且需要记住的测试方法 * window.alert(exp) 输出到警告框 * console.log(exp) 输出到控制台 * document.write(exp) 输出到页面 * id.innerHTML= 改变某一个元素的开始标签与结束标签之间的内容 ### 标识符:变量,对象的属性以及函数的名字。以数字,英文字母,_和$组成,其中数字不能作为开头。 ### 变量:存储数据的容器。 * 变量的命名规则 **var 变量名**; + 命名规则 - 首先只能由数字、字母、下划线、以及$构成。 - 其次首字母不能为数字 - 最后不能和已有关键字和库函数同名 + 不成文的命名规则 - 变量名必须用英文,不能用拼音。 - 见名知意 - 驼峰命名法:除了第一个单词之外的单词,首字母大写。 - 变量不应该重复定义 ```javascript // 声明了一个变量并且往里塞了一个值 // var 变量名 = 值; var a1 = 5; // 声明了一个变量但不赋值,此时这个变量里面存的是空值(undefined) // var 变量名; var a2; ``` ### 常量:值本身。 ### !表达式:一段具有返回值(计算结果)的语句。任何拥有返回值的语句都是表达式,反之也是成立的。 ### 运算符:将简单表达式组合成复杂表达式的方法。 ### !数据类型: **检验算法合法性的必要条件** * 基本类型: + undefind:未被赋值的变量 + null:空值 可以和undefind一样理解 + number(数字): - 1,-1,0, - NaN(not a number), - Infinity(无限), - -Infinity(负无限) 1. 整型——没有小数点的数字 2. 浮点型——有小数点的数字 + string:字符串类型——**被单引号或双引号引起来的字符** "heihei" 'hahaha' + boolean: 布尔类型——逻辑值 - true-成立 - false-不成立 * 引用类型:将Object赋值给变量a时,a引用的是Object的地址(快捷方式) + object(对象):{属性名:属性值,属性名:属性值} + function(函数) + **typeof** 可以使用 typeof 关键字查看变量类型 ```html ``` #### !表达式的副作用:如果某个表达式它的存在与否对我们整个js执行环境上下文有不同的运算结果时,我们称这个表达式是含有副作用的表达式。比如最常见的变量声明语句,这就是一个含有副作用的表达式。 ### 数值的操作方法: * parseInt(Number) 取整 **parseInt(null) -> NaN** **parseInt("1px") -> 1** * parseFloat(Number) 强制转换为数字 * 1.1111.toFixed(2)->1.11 保留几位小数; **注意:返回结果不再是Number类型而是字符串。** ### 运算符:将简单表达式组合成复杂表达式的方法。 **三要素:优先级 结合方向 操作目数** + 算数运算符 + 赋值运算符 + 自增自减运算符 + 关系运算符 + 逻辑运算符 ### 为元素绑定事件的简易方式 ```javascript // 想为一个元素绑定事件的流程: // 1.要让触发事件的那个元素持有一个id // 2.在js代码中写入如下代码 // 元素id.onclick = function(){ // 当用户点了这个元素之后才执行的代码段 // } btn.onclick = function(){ // 事件句柄 console.log(1) console.log(2) } // 被动运行事件 btn.click(); ``` ### 如何简单的获取一个input文本框中填写的内容 1. 让文本框持有一个id 2. `文本框id.value` 的返回值就是input框中目前所输入的内容(String类型);注意时机。 ### 数据类型的强制转换 #### 强制转换数据类型的方法 * Number(exp) 将表达式的返回值强制转换为数字类型。 * String(exp) ... * Boolean(exp) #### 转换规则 * 转Number - String:纯数字转换结果是字面量的形式转换,其他所有情况均为NaN。 * parseInt(Number) 取整 **parseInt(null) -> NaN** **parseInt("1px") -> 1** * parseFloat(Number) 强制转换为数字 - Boolean: **true为1,false为0**。 * 转String:所有类型转换为字符串类型就以字面量的形式进行转换。 * 转Boolean - Number:除了0和NaN以外全部为true。 - String:除了**空字符串**以外其他情况全为true。 - undefined: undefined是false。 - null:null是false。 ### ==判断相等的总结: 1. 数字和Boolean进行比较1==true为true,2==true为false. **优先将Bolean类型转成数字类型** 2. **NaN == NaN 返回false** 3. **undefined == null 返回true** ### 如何判断一个值是否为NaN: **isNaN(exp)** 如果exp的返回值是NaN则返回true。 ### ==判断具体的流程(了解) * 有NAN,一律返回false * 有布尔类型,布尔类型转换成数字比较 * 有string类型,两种情况: 1. 对象,对象用toString方法转换成string相比。 2. 数字,string类型转换成数字进行比较 * null和undefined不会相互转换,相等 * 有数字类型,和对象相比,对象用valueof转换成原始值进行比较 * 其他情况,一律返回false ### 语句 #### 条件语句(分支语句,逻辑语句) ```javascript if(exp){ 语句块 ... .... .... ..... } // if else语句 if(exp){ 分支1 } else{ 分支2 } switch(变量){ case 常量:{ 分支1; break; } case 常量2:{ 分支2; break; } case 常量3:{ 分支3; break; } default:{ 默认分支; break; } } ``` #### 循环语句 #### for语句 ```Javascript for(var i = 0;i < 100;i++){ // 循环体 console.log(i) } ``` #### while语句 #### do while语句 ```javascript while(exp){ //循环体 } // 至少执行一次版本的while语句 do{ } while(exp) ``` #### break和continue:只能出现在循环语句内部,当循环体内部执行到break关键字时,整个程序会跳出(结束)最近的循环。当循环体内部执行到continue关键字时,程序会结束本次循环的循环体进入到下一次循环。 ### 函数:一段可以被高度复用的代码段。 ```javascript // 匿名函数:不常见,就是一个没有名字的函数。 function(){ } // 声明函数 function 函数名(形参1,形参2,形参3...){ //函数体 .... } // 调用函数 函数名(实参1,实参2,实参3...) ``` ### 函数的参数 * 形参:在函数体内声明的变量,只声明不赋值。 * 实参:在调用函数时传入的参数,这里相当于是为形参赋值。 ## ! return的作用:只能出现在函数体内部。 1. 控制调用函数表达式的返回值。如果调用的那个函数体内部没有return语句,则一律返回undefined。如果调用的函数体内有return语句,则返回值是return语句后面的表达式的返回值。 2. 做流程控制,如果调用函数时执行到return语句了,那么程序会认为此次执行函数的任务就已经执行完了,就会忽略掉return语句以下的代码。 ### IIFE自调用函数 ```javascript var a = (function(n,m){ return (n+m) })(10,5) console.log(a) ``` 取三个数的中间值 ```javascript e = a>b?(ac?b:c)):(bc?a:c)) || e=ac?a:(bc?b:(a["", "sf", "sr", "g", ""] console.log(str); ``` #### JS提供的进制转换方法 1. 字符=>ASCII编码 stringObject.charCodeAt(index) 2. ASCII编码=>字符 String.fromCharCode 3. 十六进制标号 0x十六进制字符 #### ES6下的Array的全局方法 1. ***forEach()***(function(item, index, array){}) 枚举成员和下标 ```javascript var arr = [1, 5, 24, 6, 23]; arr.forEach(function(item, index, array) { // 本次循环出来的成员 console.log(item); // 本次循环的下标 console.log(index); // 本循环的数组本身 console.log(array); },arr)//第二个参数可以改变this的指向 ``` 2. ***map()*** map可以return,forEach不行 ```javascript var arr = [1, 5, 24, 6, 23]; arr.map(function(item,index,array){ // 修改原成员 return item+1; },arr)//第二个参数可以改变this的指向 ``` + 参数:item,index,array + 功能:可以修改原数组,也可以返回新数组 + 返回值:新数组 + 是否改变原数组:不会 3. ***filter()*** 可以return,并且return必须是true||false ```javascript var arr = [1, 5, 24, 6, 23]; arr.filter(function(item,index,array){ return !!(item%2); }) ``` + 参数: + 功能: + 返回值: + 是否改变原数组: 4. **some()**方法是只要一个成员的返回值是true,则整个some方法的返回值就是true,否则返回false。 5. **every()**方法是所有成员的返回值都是true,整个every方法才返回true,否则返回false。 ***注意,对于空数组,some方法返回false,every方法返回true,回调函数都不会执行。*** 6. ***reduce()*** reduce返回一个结果(不一定是数组),循环次数是整个数组长度-1,第一个参数第一次循环时代表数组的第0位,以后每一次都代表的是上一次循环的return语句的返回值;第二个参数第一次循环代表的是下标为1的那位元素,以后为下标为2,下标为3....。如果我们希望将某一个数组中的所有成员进行累计计算的话,此时是最适合reduce方法的使用的。 ```javascript var arr = [1, 5, 24, 6, 23]; arr.reduce(function(temp,temp2){ console.log(temp); return temp + temp2; }) ``` + 参数:两个参数 + 功能: + 返回值: + 是否改变原数组: ### day6 #### 对象:值得无序集合 1. 对象的声明 ```javascript var wangdawei = { "name":"王大伟", "age":18, "sex":"male", "students":[ { "name":"马燕", "age":16, "sex":"famale" } ] } console.log(wangdawei) ``` #### 对象的查询 1. Object.属性名 * 把属性名当做常量 * 在Object对象中直接查找某个属性名的所对应的属性值 2. Object["属性名"] * 把属性名当做常量 * 在Object对象中直接查找某个属性名的所对应的属性值 3. Object[属性名] * 把属性名当做变量 * 需要将该变量赋一个带双引号的属性名,并查询所对应的属性值 #### 对象的修改 1. Object.属性名=属性值 2. Object["属性名"]=属性值 #### 对象的删除 1. delete Object.属性名 + 功能:删除对应属性名 + 返回值:true||false + 是否改变原数组:不会改变原数组 #### 对象的检测 1. 属性 in Object + 功能:检测对应属性是否存在对象中 + 返回值:true||false + 是否改变原数组:不会改变原数组 #### 对象的枚举(也可用作枚举数组) 1. for(in) + 枚举属性名 for(var i in Object){ console.log(i); }; + 枚举属性值 for(var i in Object){ console.log(Object[i]); }; ### 扩展 1. console.log() + console是对象 + log是方法 2. document.white() ### JSON ### 内置对象,宿主对象 #### Math对象-方法 1. Math.abs(x) 绝对值 2. Math.ceil(x) 向上取整 3. Math.floor(x) 向下取整 4. Math.round(x) 四舍五入 5. Math.max(x,y) 取最大值 6. Math.min(x,y) 取最小值 7. Math.random() 取0-1之间的随机数 * 取0-10之间的整数 parseInt(Math.random()*1) * 取10-20之间的整数 parseInt(Math.radom()*11)+10 8. Math.pow(x,幂) 数值的次方 9. Math.sprt(x) 开平方根 10. Math.PI() π #### Date对象 存储时间 ``` javascript //如果想要使用Date对象,首先需要实例化 // 打开Date对象 var d= new Date(); ``` 1. d.getFullYear() 返回年份 2. d.getMonth() 返回月份(从0开始计数,需要+1) 3. d.getDate() 返回日期 4. d.getHours() 返回小时数 5. d.getMinutes() 返回分钟数 6. d.getSeconds() 返回秒数 7. d.getDay() 返回星期(周日返回0) 8. d.getTime() / Date.parse(日期字符串) 获取时间戳 从1970年1月1日00:00::00到现在一共经过了多少毫秒 #### 后去日期对象(非当前时间) ``` javascript var target = new Date("2021-02-12 00:00:00"); var now = new Date(); // 距离目标时间总共的秒数 var totalS = Math.floor((target.getTime()-now.getTime())/1000); // 天 var day = Math.floor(totalS/86400); // 小时 var hour = Math.floor((totalS%86400)/3600); // 分钟 var minutes = Math.floor((totalS%3600)/60); // 秒 var seconds = totalS%60; console.log(`此时距离过年还有${day}天零${hour}小时零${minutes}分零${seconds}秒`); ``` #### 定时器 1. setInterval 循环定时器 + 每隔time的毫秒数后执行一次参数一的函数体 setInterval(fun1,time); function fun1(){ console.log("执行一次"); }; 2. clearInterval 清除定时器 3. setTimeout 延迟定时器 4. clearTimeout 停止延时定时器 5. open("路径","打开页面的名字","新打开页面的外观(不能加px)") ## window对象 ### 弹出框:特点阻塞代码执行 1. alert("内容") 警告框 2. prompt([提示信息],[默认值]) 输入框 加中括号意味着可以省略 + 参数:一个或两个("提示信息","默认值") + 功能:输入框 + 返回值:为字符串 + 是否有副作用:阻塞代码执行 3. confirm([提示信息]) 确认框 + 参数:一个([提示信息]) + 功能:确认框 + 返回值:确定返回true,取消返回false + 是否有副作用:阻塞代码执行 ### location 地址对象 1. location.herf("http://www.baidu.com") 2. location.replace("index.html") location.replace("http://www.baidu.com") 覆盖原先网页,没有浏览痕迹; 3. location.reload(); 刷新 ### history对象包含用户在浏览器窗口访问过的URL。 1. back() 加载history列表中的前一个URL。 2. forward() 加载history列表中的下一个URL 3. go() 加载history 列表中的某个具体页面,或者要求浏览器移动到制定的页面数量(负数后退,正数前进) ### DOM(document object model) #### document内置对象 #### document对象下的方法 1. ***write()*** 自带字符串解析 + 参数:可以是HTML表达式或JavaScript代码。 + 功能:在页面中打印 + 返回值: + 是否有副作用:***该方法在有事件的情况下会覆盖掉全页面*** 2. ***getElementById()*** 通过id获取元素 + 参数:Id名 + 功能:通过id获取元素 + 返回值:一个Node节点 + 是否有副作用:无 3. ***getElementsByTagName()*** 通过标签获取元素 + 参数:标签名 + 功能:通过标签获取元素 + 返回值:一个NodeList/节点列表/节点集合 是一个有数组下标和Length特性的Object + 是否有副作用:无 4. ***getElementsByClassName()*** 通过class名获取元素 + 参数:class名 + 功能:通过class名获取元素 + 返回值:一个NodeList/节点列表/节点集合 是一个有数组下标和Length特性的Object + 是否有副作用:无 6. ***getElementsByName(name属性值)*** + 参数:name属性值 + 功能:通过name属性值获取元素 + 返回值:一个NodeList/节点列表/节点集合 是一个有数组下标和Length特性的Object + 是否有副作用:无 5. ***querySelectorAll("css选择器")*** 获取节点列表 ***querySelector("")***取节点 通过css选择器获取元素 + 参数:css选择器(子代选择器,群组选择器。。。)(houver不行) + 功能:通过css选择器获取元素 + 返回值:一个NodeList/节点列表/节点集合 是一个有数组下标和Length特性的Object + 是否有副作用:无 #### 根据层次关系访问节点:(包括文本和元素) 1. ***parentNode*** 返回节点的父节点 2. ***childNodes*** 返回子节点集合 3. ***firstChild*** 返回节点的第一个子节点,最常用的用法是访问该元素的文本节点 * body的第一个儿子是**回车** 4. ***lastChild*** 返回节点最后一个子节点 5. ***nextSibling*** 下一个节点 6. ***previousSibling*** 上一个节点 #### 根据层次关系访问 元素 节点: 1. ***firstElementChild*** 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 2. ***lastElementChild*** 返回节点的最后一个子节点 3. ***nextElementSibling*** 下一个节点 4. ***previousElementSibling*** 上一个节点 5. ***children*** 返回子节点的集合,具有下标属性 #### 节点的类型 通过nodeType属性来判断节点类型 1代表元素节点 3代表文本节点 #### 节点的增删查改 1. 增 * 创建节点 ***createElement*** + var oH = document.createElement("h2"); oH.innerHTML = "静夜思"; * 追加/连接 父节点.***appendChild***(newChild) newChild 被添加到孩子列表的末端 注:最后要连接body * 父节点.***insertBefore***(目标节点 , 参照节点) 将目标节点插入到参照节点之前 如果参照节点为空,则和appendChild一样 2. 删除 node.***remove***() 删除node节点 **父节点. removeChild(子节点)** 删除父节点中的子节点 ```html
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
``` 3. 查 ***hasChildNodes***判断当前的父元素是否还有子节点 返回true||false 注意,标签中的文本内容也算是节点 4. 改 node.***replaceChild***(newChild,oldChild) 用newChild节点替换oldChild节点 5. **this:一定出现在函数体内** **与事件连用时,代表触发该事件的元素本身** ### Node和NodeList是完全独立的两个存在,方法和属性都不互通 #### NodeList(节点列表/节点集合) 1. 是由若干个Node节点组成的类数组 2. 具有数组下标和Length特性 #### Node节点:Object数据类型,对应的是页面中的某个元素。 1. ***innerHTML*** 设置/获取该元素中的内容 2. ***innerText*** 该元素的文本内容 3. ***outerHTML*** 包含元素自身标签的所有内容 4. ***className*** 设置/获取该元素class属性的属性值 5. ***window.innerWidth*** 获取和设置可视窗口的宽度 #### 获取行内样式 1. ***setAttribute***("key","value") 设置该元素的某个**行内**属性的属性值 ->方法 2. ***getAttribute***("key") 获取该元素的某一个**行内**属性的属性值 ->方法 3. ***style*** 设置/获取一个元素的**行内**样式 #### 获取非行内样式(兼容问题) 1. ***getComputedStyle(obj, false)[attr]*** 针对非ie获取非行间样式 2. ***obj.currentStyle[attr]*** 针对ie获取非行间样式 3. 兼容问题 ```javascript function getStyle(obj, attr) {//获取非行间样式,obj是对象,attr是值 if (obj.currentStyle) {//针对ie获取非行间样式 return obj.currentStyle[attr];    } else { return getComputedStyle(obj, false)[attr];    //针对非ie }; }; document.write(getStyle(d, "color") + "
"); document.write(getStyle(d, "font-size")); ``` ### 分享 details标签+ contenteditable 内容可编辑 mark data datalist ## 事件 :对某个元素的某种操作 ### 事件的三要素 1. 事件元素 2. 事件类型 3. 事件对象 ### 事件对象 :当某个事件触发时产生的对象,就是事件对象 event使用前提,必须有事件,不同的对象产生的事件不同。 1. 事件对象的兼容: ```javascript document.onclick = function(evt){ var e = evt||event; console.log(e); } ``` ### 鼠标事件对象的属性 1. 坐标属性: * pageX / pageY 相对于**整个文档**左侧和顶部的坐标 * clientX / clientY 相对于**局部窗口**的左侧和顶部的坐标 * offsetX / offsetY 相对于内部元素的距离左侧和顶部的坐标(常用于拖拽) #### offset 读各种位置 读出来的结果是纯数字 使用时需要加px 1. offsetTop 2. offsetLeft 3. offsetWidth 4. offsetHeight #### style 写位置 1. style.top ### 鼠标事件类型 * **onclick** 鼠标左键点击事件 * **onmousedown** 鼠标按下事件 * **onmouseup** 鼠标松开事件 * **onmousemove** 鼠标移动事件 * **onmouseout** 鼠标移出事件 * **onmouseover** 鼠标经过事件 * **oncontextmenu** 鼠标右键点击事件 * **ondblclick** 鼠标双击事件 ##### 新增的鼠标事件 * **onmouseenter** 鼠标移动到元素内/不会触发冒泡 * **onmouseleave** 鼠标移动到元素外/不会触发冒泡 ### 键盘事件对象 1. document.onkeyup=function(){} 键盘松开事件 2. onkeydown 键盘按下事件 3. onkeypress 用户按下按键,并且产生一个字符时发生(意思是按下ctrl这类按键是没有效果的) 4. keyCode / which / charCode 获取当前输入字母的ASCⅡ码值 * ASC码转字母 String.fromCharCode(ASCⅡ码) * 10 ctrl + 回车 * 13 回车 * 32 空格 * 48-57 0-9 * 65-90 A-Z * 97-122 a-z * 兼容问题 ```javascript document.onkeypress = function(evt){ var e = evt || event; var key = e.keyCode || e.which || e.charCode; } ``` 5. ctrlKey 判断ctrl是否被按下 ``` javascript document.onkeydown = function(evt){ var e = evt || event; var key = e.keyCode||e.which||e.charCode; if(e.ctrlKey && key ==10){ console.log("发送"); } } ``` #### widow.onscroll 滚动条事件 1. scrollTop 读取和设置滚动条的垂直距离 ```html  
 

111111111111111

 

111111111111111

 
  ``` ```javascript window.onscroll = funcation(){ // 兼容问题 获取滚动条移动的垂直距离 var _top = document.body.scrollTop || document.documentElement.scrollTop; }; ``` # Day13 ### 事件流 #### 事件冒泡: 从子元素向父元素触发 onfocus 聚焦事件 onblur取消聚焦 onload当页面加载完成后 不会产生冒泡问题 1. 阻止事件冒泡 * e.stopPropagation(); 非IE * e.cancelBubble = true; IE ``` javascript document.onkeydown = function(evt){ var e = evt || event; e.stopPropagation ? e.stopPropagation() : cancelBubble = true; } ``` #### 阻止浏览器的默认行为 可以阻止a标签的跳转行为 1. e.preventDefault() 2. e.returnValue = false; 兼容写法1 ```javascript e.preventDefault?e.preventDefault():e.returnValue=false; ``` 兼容写法2 ```javascript return false; ``` #### 事件绑定的方式 1. 行内
; 2. sctipt标签内 obj.onclick = function(){} 3. addEventListener("去掉no的事件类型","回调函数","是否捕获") ### 事件监听 也是事件绑定的一种方法 #### 事件监听的好处 1. 可以为同一个元素多次绑定相同的事件 2. 可以决定当前的事件 ,是捕获还是冒泡 3. 当捕获和冒泡同时存在时,先捕获再冒泡 #### 事件元素.addEventListener("去掉no的事件类型","回调函数","是否捕获") * 第三个参数不写就是false ```javascript document.addEventListener("click",function(){ console.log(1); } document.addEventListener("click",function(){ console.log(2); } ``` #### IE的监听方法 事件源.attachEvent("不去掉on的事件"."回调函数"); #### 事件监听的兼容写法 ```javascript function addEvent(obj,type,callBack){ if(obj.attachEvent){ obj.attachEvent("on" + type,callBack); }else{ obj.addEventListener(type,callBack); } } addEvent(document,"click",function(){ alert(1); }) ``` ### 事件委托:某件事让其他元素来完成 例如:页面上有1000个li,为每个li添加单击事件,使用事件委托只需要在li的父元素上加一次事件就可以 #### 委托的好处 1. 把某个事件加到父元素上,提高程序的执行效率 2. 动态创建的元素,可以在创建元素的函数体外部为其添加事件 #### 委托的机制 1. 利用事件**冒泡**(常见) 或者事件捕获 2. 不是所有事件都可以实现事件委托,常见到的也就那么几个 #### 返回事件触发时鼠标所在的对象 1. srcElement IE 2. target 非IE 3. 兼容写法 ```javascript var target = e.target||e.srcElement; ``` 4. target.tagName 返回事件元素的名称 大写 ### JSON对象:是由若干组键值对构成 key=value 如果有一组以上的键值对 请用逗号隔开。key必须用双引号引起来。。轻量级存储工具,是一种跨平台的数据交互格式 作用:存储数据 #### json对象的定义 var json={键:值,....}; 说明: 1. 严格 模式下的json对象,键必须用双引号引起来 2. json的值可以是任意类型的 #### json对象引用:两种 ```javascript var json={ "name"="dashuai", "age"="24" } //1. console.log(json.name); console.log(json["name"]) ``` #### json对象和json字符串的相互转换 1. 对象->字符串 JSON.stringify(json); 2. 字符串->对象 var strJson = '{"name":"大帅","age":"24"}'; var json = JSON.parse(strJson); # Day14 #### 一.拖拽思路 onmousedown onmousemove onmouseout 1. 首先给目标添加一个onmousedown事件 2. 目标需要获取鼠标在文档上的位置,使用document.onmousemove获取鼠标的位置 3. 添加onmouseup事件,鼠标抬起时,取消移动事件, document.onmousemove = null; 4. 添加移动边界限制 # 正则表达式(regular expreesion) w w h 1. 什么是正则表达式:正则表达式是一个描述字符规则的对象。 如:只能出现字母||只能出现数字||前三个必须是数字等。 2. 为什么要使用正则表达式: 前端往往有大量的表单数据效验工作,采用正则表达式会使得数据效验的工作量大大减轻,如邮箱验证,手机号码等。比起用字符串的函数来判断简单的多。 3. 怎么用正则表达式 ## 正则对象的定义:两种方式 1. **var reg = / 普通字符 + 特殊字符 / 修饰符** **reg.test("目标字符串"):返回true||false** ```javascript var reg = /a/;//判断目标字符串时候至少包含一个a var str = "abc"; //reg.test("目标字符串"):返回true||false console.log(reg.test(str)); ``` 2. 构造方法 **var reg = new RegExp("普通字符+特殊字符",["修饰字符"]);** ```javascript var reg = new RegExp("a"); console.log(reg.test("heihei")); ``` 3. 普通字符:所见即所得 特殊字符:a.单个字符 b.组合字符 c.各种括号 ## 正则的特殊字符 ### 单个字符: 1. ^ :正则开始 2. $ :正则结束 3. . :元字符, 表示任意一个字符 4. \ :转义字符,可以将有超能力的字符转为普通字符 5. \+ :前面紧挨着的字符**至少出现1个**,等价于{1} 6. \* :前面紧挨着的字符**至少出现0个**,等价于{0} 7. ? : 表示其前面出现的字符至少出现过0次,至多1次,等价{0,1} 7. \- :前者到后者 8. | :或 ### 组合字符: 1. \d : 0-9之间的任意一个数字 \d只占一个位置  2. \D : 除了数字 3. \w : 数字+字母+下划线 0-9 a-z A-Z _ 4. \W : 除了\w 5. \s : 空格或者空白等  6. \S : 除了\s ### 括号: 1. {m} 标示括号前面紧挨着的字符**只能**出现m个 2. {m,}标示括号前面紧挨着的字符**至少**出现m个 3. {m,n}表示括号前面紧挨着的字符至少出现m个,至多出现n个 例: 以b开头  至少3个a  至多5个a       /^ba{3,5}&/ 4. [] 表示括号内的任意一个字符 例[wd3h] 5. [a-z]表示任意一个小写字母 例[a-zA-Z0-9] 6. [^  ]表示非括号内的任意一个字符[^wd3h] 7. [\u4e00-\u9fa5] 任意一个中文字符 8. ()一般与 或 连用 表示优先级 ## 修饰符 1. g 全局 2. i 忽略字母大小写 ## 调试:观察数据,跟踪代码的执行顺序 # day15 ### 表单验证 form 1. action:提交数据的位置 2. method :提交数据的方式 * post:武装押运 效率低,安全性高 * get: 五菱宏光 效率高,安全性低 #### onblur 鼠标失焦事件 #### submit按钮所对应的事件 onsubmit ```javascript oF.onsubmit = function(){ return true;//提交后台 return false;//不提交 //不写则默认为true; } ``` ### 正则中的相关方法及属性 #### 正则对象的方法 1. **test** 判断目标字符是否符合正则规则 + 参数:reg.test(str) + 功能:判断目标字符是否符合正则规则 + 返回值:true||false + 是否有副作用:无 2. **exec** 根据正则表达式查找,结果满足,会返回一个**长度只为1**的数组 + 参数:reg.exec(str); + 功能:根据正则表达式查找 + 返回值:结果满足,返回一个**长度只为1**的数组 + 是否有副作用:无 * reg.exec(str)[0],返回值是查找到的数据 * reg.exec(str).index,返回值是查找到的数据在原数组中的小标 3. **lastIndex** 属性用于规定下次匹配的起始位置。 * 该属性只有设置标志 g 才能使用 * 上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。 + 参数: 无 reg.lastIndex + 功能:用于规定下次匹配(test|exec)的起始位置 + 返回值:上次匹配的下标数值+1 + 是否有副作用:有,会改变下次test|exec的起始位置 #### 正则中相关字符串的方法 1. **search** :返回与正则表达式查找内容匹配的**第一个**字符串的**下标** + 参数:str.search(reg) + 功能:查找字符串 + 返回值:返回对应的第一个字符的下标 + 是否有副作用:无 2. **match** :使用正则表达式模式对字符串执行查找,并将包含查找的结果作为**数组**返回。 + 参数:str.match(reg) + 功能:查找字符串 + 返回值:一个放着查找对应字符串的数组,没有找到的话为null + 是否有副作用:无 3. **replace**:替换 + 参数:str.replace(查找的字符,替换成的字符) + 功能:替换字符串 + 返回值:替换后的字符串 + 是否有副作用:无 ## *ES6* ### let *定义变量* 1. **块级作用域** let声明的变量只在它所在的代码块有效。 2. **暂时性死区** 在被let修饰的同名变量下,根据就近原则,内部变量屏蔽外部变量。 3. **不存在变量提升** 直接报错 4. **不允许重复声明** ### this *一定出现在函数体内* 1. this与事件连用,代表触发事件的元素本身 2. this与普通函数连用,代表调用该函数的对象本身 ### bind 可以改变匿名函数的 *this* 指向 *只能为匿名函数服务* ```javascript let oBox = document.getElementById("box); document.onclick = function(){ this.style.display="none"; }.bind(oBox); ``` ### JSON.parse & JSON.stringify *严格模式* ```javascript //对象转字符串 let json = {"name":"laowang","age":"18"}; let str = JSON.stringify(json); console.log(str); //字符串转对象 let str_ = '{"name":"laowang","age":"18"}'; let json_ = JSON.parse(str_); console.log(json_); ``` ### canst 只读变量 1. *被canst修饰的变量只能读,不能改* 2. *被canst修饰的变量必须初始化* 3. *块级作用域* ```javascript // 1. const PI = 3.1415926; PI = 666;//报错 console.log(PI); // 2. const a; a = 666;//报错 ``` ### for(…in…) *遍历下标,常用于遍历json对象* ### for(…of…) *遍历json属性的属性值* # day16 ### 作业整理 ```javascript oipt.addEventListener("change", function(evt) {}) ``` 1. ***change*** 事件对象的内容被改变时,执行回调函数 ## 轮播图 ### 思路 1. 定义一个变量n来保存轮播图播放的位置 2. 给左箭头绑定点击事件,考虑边界问题,当n=0时,将n的值改为img.lenght-1 3. 给右箭头绑定事件,边界问题,当n=最大值时,将n的值改为0 4. 动态创建于img同等数量的小圆点,并赋予一个自定义属性用于保存下标 5. 点击圆点事件,并将圆点下标赋给n ### 被动触发事件 obox.click(); 事件源.去掉on的事件(); ### 运动的原理 1. 被移动的元素要有初始的行内样式 因为 **parseInt(空值)->NaN** 2. 在计时器里要不停的获取到改标签的行内样式的值,并用parseInt()或parseFloat()的方法强制转换为**数字** 3. 将得到的数字进行计算后重新赋给该元素 **注意单位** 4. 计时器的间隔时间在**16ms~32ms**之间 30帧到60帧 # day17 ## 淡入淡出轮播图 1. 点击事件中添加一个计时器,不停改变opacity的属性值。 ```javascript oBox.onclick = function(){ let fade = setInterval(function(){ let op = parsefloat(oBox.style.opacity); // 边界问题 if(op <= 0){ clearInterval(fade); oBox.style.opacity = 0; return; } obox.style.display = op - 0.03; },16) } ``` 2. 事件锁 * 定义一个全局变量lock = false * **进入点击事件时**,第一步先判断lock的值,为false时执行定时器,并将lock改为true,为true是直接返回return,不执行函数。定时器结束时,将它的值改为true; ### 横向移动轮播图思路 1. 首先图片横向排列:浮动 2. 点击向右箭头,盒子整体向左移动一个图片的宽度 3. 点击向左箭头,盒子整体向右移动一个图片的宽度 4. 边界问题,到最后一个图片,再次点击按钮的时候,在最后创建一个和第一个一样的图片,之后删掉它,并将整体位置移到第一个图片的位置 5. 同理,当在第一个图片的时候,再次点击向左按钮的时候,在第一个图片之前创建一个和最后一个一样的图片,注意添加图片后,图片可能会整体向右移动,需要重新设置图片位置。 # day18 ## 购物车 ### 注意 1. 注意js代码的**维护性** ## 根据Json对象,生成页面中的节点 ### 语句 1. box.cloneNode(true) 克隆box节点 **克隆的时候注意id不能重复** ## 面向对象 对立面是面向过程 1. 封装特性 变量变成对象的属性, 函数变成对象的方法 2. this 3. 删除后重新计算的时候,需要重新更新数量的节点集合 ```javascript let obj={ //变量 obox:document.querySelector("#box"), //方法 fun:function(){ console.log(this.obox); } } ``` ### this 出现的场景与指向问题 1. 出现在事件处理函数时,this指向触发事件的事件源节点 2. 出现在普通函数体内或在全局作用域下,this指向的是window。 3. 出现在对象的方法中,指向的是该对象本身 4. 出现在构造函数汇总,指向的是实例化对象 ### 模拟闭包 ```javascript for(let i=0;i){ (function(getI){ li[getI].onclick=function(){ console.log(getI); } })(i) } ``` ### 下半阶段课程安排 1. 前后端的数据通信 AJAX JSONP。。 2. JS的告阶 3. 本地存储 4. 后端语言PHP,NodeJs,mysql gitsvn Echarts百 度地图LBS jQuery ### 了解 1. 服务器 2. 客户端 3. 端口号 * 每个电脑都有65535的端口 * http默认敲了80号端口 * https默认敲了443号端口 4. IP地址 5. HTTP请求 6. DNS * DNS解析:将域名转换为IP地址的过程 7. 域名 8. PHPNOW * Apache Web Server类软件:打开80号端口 * PHP * Mysqln 9. shell命令 * cd 文件名:进入某个文件夹 * cd .. :退出当前文件夹 返回返回上一级 * <文件名>:执行当前文件 * <盘符:>:进去系统盘 ### AJAX(HTTP脚本化) ```javascript //1.实例化XMLHttpRequest对象 let http = new XMLHttpRequest(); //2.规划一个HTTP请求 // mehods:String,请求方式,可以是"get"也可以是"post"; // url:String,请求地址,比如"http://10.35.164.161/考试练习.html"; // async:Boolean,同步或异步,已选参数,默认是异步;false是同步; http.open(method,url,async) //3.发送HTTP请求 http.send(); //4.接收来自服务器的请求 http.onreadystatechange = function(){ if(http.readyState === 4){ console.log(http.responseText); } } ``` #### 在请求时,发送请求参数。 ```javascript // 规划了一个无请求参数的请求 http.open("get","http://10.35.164.50/message.php"); http.open("get","http://10.35.164.50/message.php?name=wangdawei&age=18&sex=1"); ``` #### 报错的原因合集 ##### JSON的正反解析 * `JSON.stringify(xxxx)` 反解析 * `JSON.parse(xxxx)` 正解析 #### MYSQL ##### 数据库的结构关系:库 > 表 > 列(字段)和行(数据) ##### 每一个表都有一个id的字段,该字段是该表的主键,并且一般来说会不为空并自动自增。 ##### 数据类型 * int 整型(整数数字) * float 浮点型(小数) * varchar 字符型(字符串) * date 日期(YYYY-MM-DD) * datetime 日期时间(YYYY-MM-DD HH:MM:SS) ##### SQL语句 **全部改为大写** ```sql -- 查数据表内所有数据 select * from 表名 -- 查根据条件查询数据 select * from 表名 where 字段名=值 select * from 表名 where 字段名=值 and 字段名=值 select * from 表名 where 字段名=值 or 字段名=值 -- 根据某个字段名进行排序 select * from 表名 order by 字段名 -- 根据某个字段名进行反向排序 select * from 表名 order by 字段名 desc -- 删除表内所有数据 delete from 表名 -- 查根据条件删除数据 delete from 表名 where 字段名=值 -- 插入新数据 insert into 表名 (字段名1,字段名2,字段名3,....) values (值1,值2,值3,.....) -- 根据条件修改数据 update 表名 set 字段名=值,字段名=值.... where 字段名=值 ``` #### cmd命令 1. `cd 文件名` 转至目标文件下 2. `cd..` 返回上一级文件 3. `cls` 清空命令 4. `ctrl c*2` 退出node环境 #### Nodejs 1. golbal node环境下代替window 2. node test.js 在cmd中运行js文件(名字不能是node.js) ##### 模块:用`require()`引入的一个对象;一类是系统模块,如fs模块,还有一类是第三方模块。 ##### fs模块 系统模块 1. 引入 `let fs = require("fs")` 2. 异步写入 **writeFile** ```javascript fs.writeFile("路径","写入的数据",function(err){ //err写入成功时为空 !!err ? console.log("写入失败") : console.log("写入成功"); }) ``` 3. 异步读取 **readFile** ```javascript fs.readFile("路径",function(err,data){//err写入成功时为空 data为读取到的数据 !!err ? console.log("读取失败") : console.log("读取成功"); console.log(data); }) ``` 4. 同步写入 **writeFileSync** ```javascript fs.writeFileSync("路径","写入的数据",function(){ console.log("写入成功"); }) ``` ### 安装第三方模块 ##### 将npm下载地址切换为国内淘宝镜像:npm config set registry http://registry.npm.taobao.org ##### 下载安装第三方模块:`npm install 模块名 --save` ##### 第三方模块官网集合:https://www.npmjs.com/ ### express(第三方模块) 接收来自前端的请求,并返回数据 1. 引入 **let express = require("express")()** 2. 计划 **express.get(route,callBack(request,response))** + callBack中的request参数是接收来自前端的数据 * request.query.属性名 + callBack中的response参数是后端给前端发送数据 * response.end() * response.send() 3. 执行监听 **express.listen(端口号)** ```javascript //计划监听 express.get("/a",function(request,response){ //request.query是来自前端的数据 console.log(`接收到来自前端的请求:${request.query.name}`); //response.end是给前端发送数据 response.send("后端接收到请求了"); }); //执行监听计划 express.listen(81); ``` ##### mysql(第三方模块) 操作数据库 1. 引入 **let mysql = require("mysql")** 2. 规划 **let sql = mysql.createConnection({})** + host : "localhost" + user : "root" + password : "123456" + database : "数据库名" + posr : 3306 *解决某个问题* 3. 尝试连接数据库 **sql.connect()** 4. 执行sql任务 **sql.query("SQL代码",callBack(err,data))** + 当SQL代码运行错误时,callBack中的err的值为空 + callBack中的data是返回的数据 ```javascript let mysql = require('mysql'); // 规划链接 let sql = mysql.createConnection({ host: 'localhost', user: 'root', password: '123456', database: 'tech', timezone: "08:00", port: 3306 }); // 尝试链接 sql.connect(); // 执行sql任务 sql.query("select * from students",function(err,data){ if(err){ console.log(err); return; } console.log(data) }) ``` #### 解决跨域问题的代码 ```javascript server.all("*",function(req,res,next){ //设置允许跨域的域名,*代表允许任意域名跨域 res.header("Access-Control-Allow-Origin","*"); //允许的header类型 res.header("Access-Control-Allow-Headers","content-type"); //跨域允许的请求方式 res.header("Access-Control-Allow-Methods","delete,PUT,POST,GET,OPTIONS"); if (req.method.toLowerCase() == 'options') res.send(200); //让options尝试请求快速结束 else next(); }) ``` ##### JSONP 另一种解决跨域问题的方法 JSONP:不是一套标准技术,而是解决跨域问题的方法之一。具体的工作机制是,前端利用一个script标签向后端发送一个HTTP请求,并且提前准备好一个回调函数,这个回调函数的函数名会在请求参数中在callback参数值中传递给后端。后端接收到来自前端发送请求后,拆解出callback参数的参数值并且以此为函数名拼接一段执行调用函数的JS代码段返回给前端并把数据当做这个函数的实参一并发送。前端接收到执行函数的代码段后会自动调用之前声明的回调函数,回调函数中的形参就代表后端返回的数据。 1. 创建一个新的script标签 2. 设置它的src属性,属性值为给后端发的请求地址,并发送一个callback的函数名。 3. 后端收到参数后,会返回一个字符串类型的带有实参的函数的调用。 4. 使用收到的实参进行进一步处理,注意,收到的数据是一个对象 ```javascript function wangxiaowei(data){ console.log(data) } let script = document.createElement("script") script.setAttribute("src","http://10.35.164.50:8080/test?callback=wangxiaowei"); document.querySelector("body").appendChild(script) ``` ##### 浏览器的同源组策略:浏览器安全防护的一种机制,它规定了一个来自某个服务器的静态文件不允许向另外一台跨域服务器发送Ajax请求。只有主机名,协议名,端口号三者都一致的情况下才会被视作是同域(或一台服务器),只要三者有任何一个不一样,那么这个Ajax请求就会被同源组策略所阻止。 ##### JSONP:不是一套标准技术,而是解决跨域问题的方法之一。具体的工作机制是,前端利用一个script标签向后端发送一个HTTP请求,并且提前准备好一个回调函数,这个回调函数的函数名会在请求参数中在callback参数值中传递给后端。后端接收到来自前端发送请求后,拆解出callback参数的参数值并且以此为函数名拼接一段执行调用函数的JS代码段返回给前端并把数据当做这个函数的实参一并发送。前端接收到执行函数的代码段后会自动调用之前声明的回调函数,回调函数中的形参就代表后端返回的数据。 #### 下载Node全家桶: npm install mysql express express-static ejs --save #### 模板引擎 ejs ```javascript ejs.renderFile("details.html",{info:data[0]}, function(error,result){ if(error){ console.log(error) return; } response.end(result) }); ``` #### expresse-static:NodeJS环境中向前端提供静态服务的第三方模块,可以代替Apache。 ``` javascript const server = require("express")(); const expressStatic = require("express-static") const mysql = require('mysql'); const port = 8080; // 拦截所有请求,并且声明静态请求目录 server.use(expressStatic(`${__dirname}/static`)); ``` #### express static 1. npm install mysql express ejs --save ### jQuery * 获取节点 1. **$("css选择器")** 获取jQuery对象 + 参数:css选择器 + 功能:获取jQuery对象 + 返回值:*jQuery对象* + 是否有副作用:无 2. **$("node节点")** 将Node节点转换成jQuery节点 + 参数:node节点 + 功能:将node节点转换成jQuery对象 + 返回值:*jQuery对象* + 是否有副作用:无 3. **$("HTML代码段")** 类似于创建节点 + 参数:HTML代码段 + 功能:创建节点 + 返回值:*jQuery对象* + 是否有副作用:无 4. **$(function(){})** 类似于window.onload事件,完全等价于document.onready * 操控Jquery对象类名 1. **addClass()** 添加类名 + 参数:类名 + 功能:给jquery对象添加类名 + 返回值:*调用该方法的jQuery对象本身* + 是否有副作用:添加一个类名 2. **removeClass()** 删除类名 + 参数:类名 + 功能:删除jquery对象的一个类名 + 返回值:*调用该方法的jQuery对象本身* + 是否有副作用:删除jquery对象的一个类名 3. **toggleClass()** 开关类名 + 参数:类名 + 功能:添加|删除jquery对象的一个类名 + 返回值:*调用该方法的jQuery对象本身* + 是否有副作用:添加|删除jquery对象的一个类名 4. **hasClass()** 判断是否有该类名 + 参数:类名 + 功能:判断jquery对象的一个类名 + 返回值:true|false + 是否有副作用:无 * 操控Jquery对象 1. **remove()** 删除节点 + 参数:类名 + 功能:删除jquery对象 + 返回值:*调用该方法的jQuery对象* + 是否有副作用:无 2. **clone()** 克隆节点 + 参数:**true** + 功能:传true的话可以克隆事件 + 返回值:克隆好的jQuery对象 + 是否有副作用:无 3. **父节点.append(节点)** 添加节点到**最后** + 参数:添加的jQuery对象 + 功能:添加节点 + 返回值:调用该方法的的jQuery对象 + 是否有副作用:添加节点 4. **节点.appendTo(父节点)** + 参数:添加的jQuery对象 + 功能:添加节点 + 返回值:调用该方法的的jQuery对象 + 是否有副作用:添加节点 5. **prepend()** 添加节点到**第一个** 6. **prependTo()** **参数为父节点** 7. **参考点.after(节点)** 添加节点到参数节点之**后** + 参数:参考点 + 功能:添加节点到参数节点之**后** + 返回值:调用该方法的的jQuery对象 + 是否有副作用:添加节点 8. **参考点.before(节点)** 添加节点到参数节点之**前** + 参数:参考点 + 功能:添加节点到参数节点之**前** + 返回值:调用该方法的的jQuery对象 + 是否有副作用:添加节点 * 操控HTML 1. **html()** 传参=设置,不传=获取,等同于innerHTML + 参数:文本或HTML代码 + 功能:传参为设置标签中的内容,不传参为获取标签中的内容 + 返回值:调用该方法的jQuery对象 + 是否有副作用:传参时会改变HTML标签的内容 2. val() 设置/获取 传参/不传 3. attr() 设置/获取属性 传两个参数/不传 - 第一个参数是属性,第二个是属性值 - 当获取的对象是一个**节点集合**,那么返回值只是第一个节点的属性值 4. css() 设置行内样式 + 参数:一个||两个|**一个对象** + 功能:设置行内样式 + 返回值:*调用该方法的jQuery对象* + 是否有副作用: ```javascript $("div").css({ fontSize:12, marginLeft:300, }) ``` 5. animate() 动画 + 参数:对象、时间、回调函数 + 功能:动画设置行内样式 + 返回值:*调用该方法的jQuery对象* + 是否有副作用: * 节点的遍历 1. closest() + 参数:css选择器 + 功能:**向上**寻找该父代元素, + 返回值:寻找到的jquery对象 2. find() + 参数:css选择器 + 功能:**向下**寻找匹配的后代元素 + 返回值:寻找到的jquery对象 3. next() + 参数:无 + 功能:寻找下一个元素 + 返回值:寻找到的jquery对象 4. prev() 获得匹配元素集合中每个元素紧邻的前一个同辈元素 5. parent() 获得当前匹配元素集合中每个元素的父元素 6. eq() + 参数:index + 功能:从jquey结果中提取一个对象 + 返回值: 7. each() + 参数:回调函数 + 功能:枚举 + 返回值:this是指每个节点 8. index() + 参数:无 + 功能:查找该元素在父元素中对应的下标 + 返回值:this是指每个节点 * 控制显示隐藏 1. show() 显示 hide() 隐藏 toggle() 隐藏|显示 2. fadeIn() 淡入 + 参数:第一个参数时间ms,第二个参数是回调函数(执行完后再执行函数) fadeout() 淡出 fadeToggle() 3. slideDown() 下拉显示 + 参数:第一个参数时间ms,第二个参数是回调函数(执行完后再执行函数) slideUP() 下拉收起 slideToggle() * jquery对象绑定事件 ``` javascript $(".btn").click(function(){ alert(1); console.log(this); //this还是node节点,调用jquery方法时需要转成jquery对象 }) ``` ##### jQuery ajax ```javascript $.ajax({ url:"http://10.35.164.50:8080/test", data:{ id:1, name:"wangdawei" }, dataType:"jsonp", method:"GET", async:false, // HTTP请求成功之后触发的回调 success:function(data){ console.log(data) }, // HTTP请求成功失败触发的回调 error:function(){ }, // HTTP请求结果接收到之后触发的回调 complete:function(a,b){ console.log(a.responseText) }, beforeSend:function(){ console.log("正准备发送请求") }, //修改jsonp请求中带有函数名参数的名字(一般默认是callback) jsonp:"cb" // 修改回调函数的函数名 jsonpCallback:"wangdawei" }) ``` ### 构造函数 ```javascript function Preson(name,sex,age){ //let o ={} this.name = name; this.age = age; this.sex = sex; this.type = "灵长类"; //return o } new Preson("王大伟","男",18) ``` new 关键字为我们做了什么 1. 在构造函数里先声明一个空对象 2. 将本函数中的this指向改变刚才声明的对象 3. 在函数体最后将该对象return; new 可以称为实例化对象 ### 原型对象 prototype #### 原型的理解:每一个构造函数都有一个prototype属性,该属性指向了一个对象,这个对象我们叫原型对象。通过构造函数生成的实例化对象,如果在调用属性或方法时从自身找不到该属性或方法,此时不会直接报错或返回undefined,而是去找它的构造函数的原型对象,看它里面有没有该属性或方法,如果有则直接借用,如果没有则看看该原型对象还有没有prototype属性,如果有则重复上面的操作,如果没有则返回undefined或报错。 ###### 用途 * 为本地对象扩展原型方法 * 将构造函数中重复的属性或方法从私有属性与私有方法中提取出来,放到构造函数的原型对象中,从而减少内存的开销 ##### JS的继承 ```javascript // es5继承 function Person(name,sex,age){ this.name = name; this.age = age; this.sex = sex; } Person.prototype.type = "灵长类"; function SuperMan(name,sex,age,skill){ // 继承来自父类Person的所有私有属性 Person.apply(this,[name,sex,age]); this.skill = skill; } // 继承来自父类Person的所有的原型属性和原型方法 SuperMan.prototype = new Person(); SuperMan.prototype.fadazhao = function(){ alert(this.skill) } let spiderMan = new SuperMan("蜘蛛侠","男",18,"吐丝儿") ``` ##### call和apply区别:call和apply都是函数的方法,该方法可以帮助函数调用一次自己,但是和普通调用不同,call和apply的调用可以调整本次执行函数中this的指向,这个指向会被第一个参数代替。如果这个函数在调用数需要传递实参,那么call方法会把实参依次排列在第一的参数之后,而apply则是将实参放到一个数组中,并把数组作为apply方法的第二个参数。call和apply常常被用在构造函数实现继承功能的场景下。 ```javascript function fn(num1,num2){ console.log(this) console.log(num1 + num2) } // 以下的两种写法是完全等价的。 fn() fn.call() // 调用并改变本次函数的this指向 fn.call(1) // 调用并改变本次函数的this指向并传入实参 fn.call("hello",1,2) // 调用并改变本次函数的this指向 fn.apply(1) // 调用并改变本次函数的this指向并传入实参 fn.apply("hello",[1,2]) ``` ##### ES6的类和继承 ```javascript class Person { constructor(name,age,sex){ this.name = name; this.age = age; this.sex = sex; } sayName(){ alert(this.name) } } let wdw = new Person("王大伟",18,'男') class SuperMan extends Person{ constructor(name,age,sex,skill){ // 继承父类的私有属性 super(name,age,sex) this.skill = skill } dazhao(){ alert(this.skill) } } let gangtiexia = new SuperMan("钢铁侠",18,"男","钞能力"); class Person { constructor(name,age,sex){ this.name = name; this.age = age; this.sex = sex; } sayName(){ alert(this.name) } } let wdw = new Person("王大伟",18,'男') class SuperMan extends Person{ constructor(name,age,sex,skill){ // 继承父类的私有属性 super(name,age,sex) this.skill = skill } dazhao(){ alert(this.skill) } } let gangtiexia = new SuperMan("钢铁侠",18,"男","钞能力"); ``` ##### JS如何实现继承 ### cookie #### 设置一个会话cookie + **document.cookie = "name=wdw"** #### 设置存储日期 ```javascript let date = new Date("2020-12-05-00:00:00") document.cookie = `name=wdw;expires=${date}` ``` #### 设置cookie ```javascript function setCookie(key,value,expires){ if(typeof expires === "number"){ let date = new Date(); date.setDate(date.getDate()+expires); document.cookie = `${key}=${value};expires=${date}`; }else{ document.cookie = `${key}=${value};expires=${expires}` } } setCookie("name","wdw",new Date()) ``` #### 读取cookie document.cookie是一个**字符串**,需要转换成对象 ```javascript function getCookie(key){ let cookie = document.cookie; let arr = cookie.split("; ")//分号+空格 let result = {}; arr.forEach(item=>{ let key = item.split("=")[0]; let value = item.split("=")[1]; result[key] = value; }) if(key){ return result[key]; } return result; } ``` #### 删cookie ```javascript function removeCookie(key){ let formerly= new Date("1970-01-01 00:00:00") if(key){ document.cookie = `${key}=bey;expires=${formerly}` }else{ let cookie = getCookie(); for(let i in cookie){ document.cookie = `${key}=bey;expires=${formerly}` } } } ``` ### localStorage/sessionStorage ```javascript //设置 localStorage.setItem("name","wdw") //获取 localStorage.getItem("name") //删除 localStorage.removeItem("name") //清空 localStorage.clear() //length属性 localStorage.length ``` ### cookie,localStorage,sessionStorage之间的区别 * cookie:操作麻烦,需要大量的字符串处理。兼容性好,数据的生命周期可以灵活的设置。 * localStorage:想丢与cookie来说兼容性较差,数据的生命周期是永久性存储。 * sessionStorage:数据生命周期在会话期(在当前标签页中),其余的所有特性都类似于localStorage。 ### jquery方法 * prop() 用于检索属性值 ### input标签的使用 * setSelectionRange ```javascript //全选input框中的内容 input.setSelectionRange(0, input.value.length); ``` ### 闭包 ```javascript let fun = (function(){ var a = 5; return function(){ a++; return a; } })(); console.log(fun());//6 console.log(fun());//7 ``` ```javascript function fn(){ var i = 0; function fun(){ i++; console.log(i); } return fun; } var run = fn(); run();//1 run();//2 var run2 = fn(); run2();//1 run2();//2 ``` + 闭包是什么 闭包是在函数体内部return另外一个函数体,并且将外层函数利用IIFE的写法直接将其调用并将内层函数的引用返回给一个变量。 1. 让外部访问函数内部变量成为可能; 2. 可以避免使用全局变量,防止全局变量污染; 解决的问题是可以将全局变量变成一个局部变量,并且该变量被修改的唯一途径就是调用内层函数。 缺点是这个变量会常驻在内存中,可能造成内存泄漏(有一块内存空间被长期占用,而不被释放) ### GIT:版本控制系统 + git的区域包括 1. 工作区 2. 缓冲区:临时的落脚点 3. 版本区 + git本地命令 1. **git init** 初始化仓库 2. **git status** 查询仓库 - 红色代表未进入缓冲区 - 绿色代表文件已在缓冲区 3. **git add -A** 将工作区的所有文件提交到缓冲区 4. **git commit -m "注释"** 将缓冲区的文件提交到版本区,并清空缓冲区,*必须要注释* 5. **git checkout -- 文件名** 撤销修改 6. **git diff 文件名** 对比文件 7. **git log** 查询版本区 8. **git reflog** 查询历史动态 9. **git reset --hard 版本号** 将工作区调整到对应版本上 10. **ssh-keygen -t rsa -C "邮箱"** 导出公匙和私匙 11. **git commit -am "注释"** 将所有工作区内修改的文件绕过缓冲区直接提交到版本库 12. **git push** 将本地版本库的内容同步到远程库 13. **git clone** 将远程库克隆到本地 14. **git pull** 将远程库文件拉到本地