
博客
-
__proto__隐式原型
是什么
对象的一个属性
有什么用
对象可以通过
__proto__
访问到构造函数的原型对象当一个实例访问属性时, 在自己身上没有找到时, 会自动根据
__proto__
找到原型对象, 去找原型对象上的属性···(拓展:原型链)function Person() {} let per = new Person() per.__proto__ === Person.prototype
总结
对象的
__proto__
等价于 构造函数的prototype
属性 -
原型prototype
- 函数本质上也是对象, 所以函数也有属性
- 函数有
prototype
属性:属性值是个对象,叫做原型(对象) prototype
属性的作用:通过构造函数创建出来的实例对象可以直接去访问这个原型对象上的任意属性和方法
prototype 是函数特有的属性, 只有函数能使用
是什么
函数的一个属性,值是一个对象,我们也称为
prototype
的值为原型(对象)有什么作用
共享方法
使用目的
解决内存浪费问题
使用构造函数批量创建对象,多个对象有共同方法时会产生内存浪费问题
我们可以把重复的一样的方法,添加到原型对象中,这样所有通过该构造函数创建的实例对象,都可以共享此方法。
//声明函数 function Person() {} //给原型对象添加属性和方法 Person.prototype.gender = '男' Person.prototype.doSomething = function(){ console.log('干啥呢') } //创建实例对象 let first = new Person() //实例对象调用原型对象中的属性和方法 first.gender //男 first.doSomething() //干啥呢
总结
在原型对象上添加方法, 让所有实例对象共享, 可以保证内存的不浪费
- 对象的属性一般写在构造函数中,属性添加给了实例对象自身
- 对象的方法写在原型对象中,方便让所有实例对象共享
constructor属性
- 原型对象自带的属性
- 该属性值指向了当前的构造函数
是什么
原型对象里的一个属性, 指向了构造函数方法
function Person () {} let first = new Person() Person.prototype === Person first.__proto__.constructor === Person
实例对象本身没有constructor属性,实例对象可以直接访问原型对象的属性。
-
构造函数
使用构造函数的目的
批量创建对象
使用
- 构造函数也是函数
function
- 构造函数 函数名首字母需要大写(规范)
- 构造函数 必须和
new
一起使用创建对象 (批量)
//声明函数 function Person(nameValue) { this.name = nameValue } //创建实例对象 // new 出来的对象称之为实例对象 let first = new Person('Liao') let Second = new Person('Xin')
优点
- 不需要手动声明对象和返回对象
- 有具体的类型, 类型是当前的构造函数名称(例:Person)
注意点:必须配合
new
使用new的时候做了四件事情
- 创建一个新对象(在内存中开辟新空间)
- 将
this
指向创建的新对象 - 执行构造函数内代码(本质上:给新对象添加属性)
- 把创建的新对象给返回
实例(对象):构造函数创建出来的对象
拓展
通过对象字面量批量创建
let obj1 = {name: '小黑'} let obj2 = {name: '小白'} let obj3 = {name: '小红'} let obj4 = {name: '小绿'}
不足
需要创建多个有着共同属性的对象会非常麻烦
工厂函数
批量创建对象
function createPerson(nameValue) { // 1.创建一个新对象 let person = {} // 等价new Object() // 2.给对象添加对应的属性 person.name = nameValue // 3.返回该对象 return person } let third = createPerson('Shang') let fourth = createPerson('Li')
不足
- 需要手动创建对象和返回这个对象
- 创建出来的对象类型统一是
object
, 无法识别对象的具体类型
- 构造函数也是函数
-
express的简单使用
需要提前安装node.js
初始化
vscode资源管理器空白部分右击 – 在集成终端中打开
终端输入命令
npm init --yes
安装express框架
npm i express
新建一个js文件:
//1. 引入express const express = require('express'); //2. 创建应用对象 const app = express(); //3. 创建路由规则 // request 是对请求报文的封装 // response 是对响应报文的封装 app.get('/', (request, response)=>{ //设置响应 response.send('HELLO EXPRESS'); }); //4. 监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动, 8000 端口监听中...."); });
在vscode中右键项目文件夹,在集成终端中打开
在终端中输入
node express.js
-
jQuery中的AJAX
GET
$.get(url,[data],[callback])
url:请求地址
data:请求时携带的参数
callback:请求成功的回调函数
$.get('https://api.liaooo.cn/api', { id: 1, name: 2 }, function (result) {})
POST
$.post(url,[data],[callback])
url:请求地址
data: 要提交的数据
callback:请求成功的回调函数
通过$.ajax()发送请求
$.ajax(url,[settings])
$.ajax({ type: 'GET', //请求方式 url: 'https://api.liaooo.cn/api', //请求的URL地址 data: { id: 1, name: 2 }, //请求携带的数据 success: function(result){ }, //请求成功回调 })
-
HTTP
HTTP协议(hypertext transport protocol)(超文本传输协议),协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求报文
重点是格式与参数
行 POST /wp-json/wp/v2/categories HTTP/1.1 头 Host: liaooo.cn Cookie: 5c57847f5465a2bf45c8953d097c5486 Content-type: application/x-www-form-urlencoded User-Agent: ··· Chrome/100.0.4896.60 Safari/537.36 ··· 空行 体 username=admin&password=123
响应报文
行 HTTP/1.1 200 OK 头 Content-Type: text/html;charset=utf-8 Content-length: 2048 Content-encoding: gzip 空行 体 {"id":123,"link":"https:\/\/liaooo.cn\/topic\/html\/","name":"HTML"}
常见响应状态码
404
服务器找不到请求的资源403
客户端没有访问内容的权限401
客户端必须对自身进行身份验证才能获得请求的响应500
服务器遇到了不知道如何处理的情况200
请求成功
HTTP 请求方法
GET
用于提交少量的、简单的数据。
GET方法用于使用给定的URI从给定服务器中检索信息,即从指定资源中请求数据。使用GET方法的请求应该只是检索数据,并且不应对数据产生其他影响。
注:因GET请求的不安全性,在处理敏感数据时,绝不可以使用GET请求。
POST
- 用于提交大量的、复杂的、包含文件上传的数据
- 实际开发中,form表单的post提交方式用的较多
请求主体的类型由
Content-Type
头部指定.POST方法用于将数据发送到服务器以创建或更新资源,它要求服务器确认请求中包含的内容作为由URI区分的Web资源的另一个下属。
POST请求永远不会被缓存,且对数据长度没有限制;我们无法从浏览器历史记录中查找到POST请求。
-
AJAX
1.创建一个实例化对象
new XMLHttpRequest()
let xhr = new XMLHttpRequest()
2.设置请求信息
xhr.open(method, url);
*.设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3.发送请求
xhr.send(body)
get 请求不传 body 参数,只有 post 请求使用
4.接收响应
xhr.responseXML
接收 xml 格式的响应数据xhr.responseText
接收文本格式的响应数据xhr.onreadystatechange = function (){ if(xhr.readyState == 4 && xhr.status == 200){ var text = xhr.responseText; console.log(text); } }
IE缓存问题
在IE中,ajax的同一请求只会请求一次,重复请求会加载缓存的数据
解决方法
浏览器缓存根据url记录,动态更新url即可避免
可在请求url后面加随机数、时间戳等
xhr.open("get","/testAJAX?t="+Date.now());
属性
当 readyState 属性发生变化时
xhr.onreadystatechange
也可使用
addEventListener()
来监听请求的状态码
xhr.readyState
- 0: 表示
XMLHttpRequest
实例已经生成,但是open()
方法还没有被调用 - 1: 表示
send()
方法还没有被调用,仍然可以使用setRequestHeader()
,设定 HTTP请求的头信息 - 2: 表示 send()方法已经执行,并且头信息和状态码已经收到
- 3: 表示正在接收服务器传来的 body 部分的数据
- 4: 表示服务器数据已经完全接收,或者本次接收已经失败了(请求完成,不一定成功)
响应体
xhr.response
xhr.responseText
定义响应类型
xhr.responseType
值
text
、json
等响应状态
xhr.status
返回状态码 例:
200
最大请求时间(毫秒)
xhr.timeout
若超出该时间,请求会自动终止。
请求超时调用
xhr.ontimeout
也可使用
addEventListener()
来监听
方法
中止请求
xhr.abort()
获得响应头
xhr.getResponseHeader()
初始化一个请求
xhr.open()
设置 HTTP 请求头的值
必须在
open()
之后、send()
之前调用xhr.setRequestHeader()
发送请求
xhr.send()
事件
当请求被停止时触发
abort
当请求遭遇错误时触发
error
请求成功完成时触发
load
在预设时间内没有接收到响应时触发
timeout
- 0: 表示
-
css隐藏移动端滚动条
html::-webkit-scrollbar, body::-webkit-scrollbar { display: none; } html, body { height: 100%; overflow: hidden; overflow-y: scroll; /* 使得ios滑动流畅 */ -webkit-overflow-scrolling: touch; }
PS : 设置
height: 100%; overflow: hidden; overflow-y: scroll;
是重点 -
jQuery
jQuery对象
用jQuery方式获取过来的对象是jQuery对象.
$("div"); // $("div")是一个jQuery 对象
jQuery 对象只能使用 jQuery 方法
jQuery对象转换为DOM对象
//加上索引号即可转为DOM对象,可以使用DOM对象的方法 $("div")[0] $("div").get(0)
隐式迭代
隐式迭代就是把匹配的所有元素内部进行遍历循环.
<div>我们一起被修改</div> <div>我们一起被修改</div> <div>我们一起被修改</div> <div>我们一起被修改</div> <script> $("div").css("background", "pink"); //隐式迭代直接把元素遍历了一遍,可以直接修改所有div样式 </script>
筛选选择器
$(function() { $("ul li:first").css("color", "red"); //:first :last $("ul li:eq(2)").css("color", "blue"); //选择第n个元素 :eq(n) $("ol li:odd").css("color", "skyblue"); //奇数 $("ol li:even").css("color", "pink"); //偶数 //注意:索引号从0开始 })
筛选方法
parent()
查找最近父级
$("li").parent();
parents()
可返回指定父级,如果参数为空,返回所有父级.
$("li").parents("选择器");
children(“选择器”)
相当于
$("ul>li")
最近一级(亲儿子)$("ul").children("li");
find(“选择器”)
相当于
$("ul li")
,后代选择器$("ul").find("li");
siblings(“选择器”)
查找兄弟节点(不包括自己)
$(".first").siblings("li");
eq(index)
相当于
$("li:eq(2)");
方法里面可以换成变量,比较灵活$("li").eq(2);
nextAll()
查找当前元素之后的所有同辈元素
$(".first").nextAll();
prevtAll()
查找当前元素之前的所有同辈元素
$(".last").prevtAll();
hasClass(“类名”)
查找元素是否含有某个类,返回值true or false.
$("div").hasClass("box");
得到当前元素索引号
方法
$(this).index();
排他思想
利用查找兄弟元素的方法
siblings("选择器")
选择兄弟节点,除了自己$("div").eq(1).show(); $("div").eq(1).siblings().hide();
链式编程
//上个小节的代码可以改写为这样 $("div").eq(1).show().siblings().hide();
操作CSS方法
参数只写属性名,返回值是属性值.
$("div").css("color"); //#333
修改CSS样式
$("div").css("属性名","属性值"); //逗号分隔,属性必须加引号,值是数字不用加单位和引号
修改多个CSS样式(利用对象)
$("div").css({ 属性名:"属性值" //如果值不是数字,则需要加引号 width: 400, color:"lightblue" backgroundColor: "red" // 如果是复合属性则必须采取驼峰命名法 });
设置类样式方法(原生的classList)
添加类
$("div").addClass("active");
移除类
$("div").removeClass("active");
切换类
$("div").toggleClass("active"); //有就移除,没有就添加
jQuery效果
[]
内表示可以省略speed:
三种预定速度之一的字符串(“slow”,”normal”, or “fast”)或表示动画时长的毫秒数值(如:1000)easing:
要使用的擦除效果的名称(需要插件支持).默认jQuery提供”linear” 和 “swing”.fn:
在动画完成时执行的函数,每个元素执行一次.停止排队
stop()
必须写在动画的前面,相当于结束上一次动画.
显示 / 隐藏 / 切换
show([speed],[easing],[fn])
hide([speed],[easing],[fn])
toggle([speed],[easing],[fn])
滑动
slideDown([speed],[easing],[fn])
slideUp([speed],[easing],[fn])
slideToggle([speed],[easing],[fn])
事件切换
hover([overfn,]outfn)
相当于
mouseover
和mouseout
hover(fn1(){},fn2(){}) //over:鼠标移到元素上要触发的函数 //out:鼠标移出元素要触发的函数 //如果只写一个函数,则鼠标移入移出都会触发
淡入淡出
fadeIn([speed],[easing],[fn])
fadeOut([speed],[easing],[fn])
fadeToggle([speed],[easing],[fn])
fadeTo(speed,opacity,[easing],[fn])
//时间和透明度必须写自定义动画
animate(params,[speed],[easing],[fn])
params:
一组包含作为动画属性和终值的样式属性和及其值的集合获取属性
获取元素固有属性值
获取属性值
ele.prop("属性名")
修改属性值
ele.prop("属性名",[值])
获取自定义属性值
自定义和自带的都能用
获取自定义属性值
ele.attr("自定义属性名")
//类似原生 getAttribute()
修改自定义属性值
ele.attr("自定义属性名",[值])
//类似原生 setAttribute()
H5新增的
data-*
也可以用这个方法得到数据缓存
data([key],[value])
当参数只有一个key的时候,为读取该jQuery对象对应DOM中存储的key对应的值,值得注意的是,如果浏览器支持HTML5,同样可以读取该DOM中使用 data-[key] = [value] 所存储的值.
设置
$("span").data("uname", "andy"); //不会出现在DOM上,存在内存中
使用
$("span").data("uname"); //andy
读取的data-[key]值
<div data-test="this is test" ></div> $("div").data("test"); //this is test!; //不需要加data-
jQuery 内容文本值
获取设置元素内容 html()
console.log($("div").html());
修改内容
$("div").html("123");
获取设置元素文本内容 text()
console.log($("div").text());
修改内容
$("div").text("123");
获取设置表单值 val()
console.log($("input").val());
修改内容
$("input").val("123");
遍历元素
$().each(fn("索引号",对应DOM对象))
主要用于遍历DOM对象
两个参数均可自己命名
<div>1</div> <div>2</div> $("div").each(function(i, domEle) { // 0 1 console.log(i); //<div>1</div> //<div>2</div> console.log(domEle); })
$.each(arr,fn(索引号,ele){})
主要用于遍历数据,处理数据.
$.each({ name: "andy", age: 18 }, function(i, ele) { console.log(i); // 输出的是 name age 属性名 console.log(ele); // 输出的是 andy 18 属性值 })
创建添加删除元素
创建
$("<li> 小li </li>");
添加
内部添加(和获取元素是父子关系)
放到最后一个
$("ul").append($("<li> 小li </li>"));
$("ul").prepend($("<li> 小li </li>"));
放到第一个外部添加(和获取元素是兄弟关系)
放到后面
$("div").after("<div>新的div</div>");
$("div").before("<div>新的div</div>");
放到前面删除
删自己
$("div").remove();
//删子元素
$("div").empty();
相当于清空自己的所有内容$("div").html("");
相当于修改元素内的内容jQuery 尺寸
width() / height()
获取设置元素 width和height大小
$("div").width()
innerWidth() / innerHeight()
获取设置元素 width 和 height + padding 大小
$("div").innerWidth()
outerWidth() / outerHeight()
获取设置元素 width 和 height + padding + border 大小
$("div").outerWidth()
outerWidth(true) / outerHeight(true)
获取设置 width 和 height + padding + border + margin
$("div").outerWidth(true)
jQuery 位置
获取设置距离文档的位置(偏移) offset
(与父级无关)
$("div").offset()
有两个属性
left
、top
获取
$("div").offset().top;
设置偏移
$("div").offset({top:100,left:30});
获取距离带有定位父级位置(偏移) position
(如果没有带有定位的父级,则以文档为准)
position方法不能设置偏移,其余用法和offset一样
被卷去的头部
被卷去的头部
scrollTop()
被卷去的左侧
scrollLeft()
填数值可以将页面跳转到对应位置
返回顶部小例子
(注意是获取body和html元素,而不是文档)
$("body, html").stop().animate({ scrollTop: 0 }); // $(document).stop().animate({ // scrollTop: 0 // }); 不能是文档而是 html和body元素做动画
jQuery 事件处理
单个事件注册
$("div").事件名(fn(){})
事件处理 on
绑定多个事件
//绑定多个事件,每个事件对应不同函数 $("div").on({ mouserenter:fn(){}, cilck:fn(){}, dbclick:fn(){}, }) //绑定多个事件,事件之间用空格隔开,对应相同函数 $("div").on("mouseenter mouseleave", function() {});
事件委派
$("绑定事件的元素").on("click", "触发的元素", fn() {});
$("ul").on("click", "li", function() { alert(11); }); //click 是绑定在ul 身上的,但是 触发的对象是 ul 里面的小li
on可以给未来动态创建的元素绑定事件
$("ul").append("<li> </li>"); //新加的小li也绑定了事件
事件解绑 off
$("div").off();
解除所有事件$("div").off("click");
解除某个事件$("ul").off("click", "li");
解除事件委托绑定只触发一次的事件
$("p").one("click", function() {})
自动触发事件
默认行为 例:文本框focus会有光标闪烁
元素.事件()
$("div").click();
会触发元素的默认行为元素.trigger(“事件”)
$("div").trigger("click");
会触发元素的默认行为元素.triggerHandler(“事件”)
$("div").triggerHandler("click");
不会触发元素的默认行为jQuery 事件对象
和原生差不多
$("div").on("click", function(event) { // console.log(event); console.log("点击了div"); event.stopPropagation(); //阻止冒泡 })
jQuery 拷贝对象
$.extend([deep], target, object1, [objectN])
参数
deep:如果设为true,则为深拷贝
target:待修改对象。
object1:待合并到第一个对象的对象。
objectN:待合并到第一个对象的对象(可选)。
var targetObj = { id: 0, msg: { sex: "男" } }; var obj = { id: 1, name: "andy", msg: { age: 18 } };
浅拷贝把原来对象里面的复杂数据类型地址拷贝给目标对象
targetObj
将会被obj
中的同名属性覆盖- 但是,
obj
中的msg属性值是对象,浅拷贝只会拷贝msg的地址,所以targetObj
打印出来的msg和obj指向同一地址
$.extend(targetObj,obj); targetObj.msg.age = 20; //两个对象中的msg指向同一地址,所以都会被修改
深拷贝把里面的数据完全复制一份给目标对象
(如果里面有不冲突的属性,会合并到一起)
- 因为是深拷贝,
obj
把属性复制一份给targetObj
,所以如果targetObj
中有和obj
同名的属性,则会被覆盖 - 像
obj
的msg中的age则会合并到targetObj
的msg里面 - 如果如
targetObj
中的msg原来有age,则会被覆盖
$.extend(true, targetObj, obj); targetObj.msg.age = 20;
jQuery 多库共存
- 如果
$
符号冲突 我们就使用jQuery
- 让
jquery
释放对$
控制权 自己来决定
var diy = jQuery.noConflict(); console.log(diy("span")); diy.each();
jQuery 插件
瀑布流、图片懒加载、全屏滚动···