1、animate.css文件是一个动画库
如何使用:
1、打开:animate.style/
2、下载
3、引入animate文件
4、挑选,将class放在使用动画的元素上
5、设置上animate-duration:几秒钟,时长,如果不想自己设置,提供了"animate_animated"只能1s
6、设置初始效果
swiper插件
1、搜索swiper
2、点击swiper按钮
3、点击导航条上的在线演示
4、挑选一个,右键查看源代码
封装运动(动画)函数
function animate(selector,obj){
let elem=document.querySelector(selector);
for(let i in obj){
elem.style[i]=obj[i]
}
}
高德/百度地图:
1、打开百度搜索:百度地图开放平台
2、注册/登录
3、拉到最下面,注册成为开发者
4、应用管理->我的应用->创建应用->用户名->选择浏览器端->0.0.0.0/0
5、得到密钥
6、导航栏->开发文档->JSapi->示例demo->挑选复制->修改css/js代码,查询在线经纬度(百度地图拾取坐标系统)
7、注意:GL只能和GL混搭,普通版只能和普通版混搭
8、VScode只能使用live server打开
object:封装、继承、多态
1、面向对象:任何操作都要封装在一个对象之中
面对过程:先干什么,再干什么,最后干什么
2、封装:
1、直接量方式:
let obj={
"属性名":属性值,
"方法名":function(){}
}
2、访问对象的属性和方法:
对象名.属性名===对象名["属性名"]
对象名.方法名===对象名["方法名"]
3、访问到不存在的属性返回的是undefined
4、添加新属性、方法:
obj.属性名=属性值
obj.方法名=function(){}
5、必须使用for in循环进行遍历且obj[i]才能够拿到,obj.i只能得到undefined
6、如果要在对象的方法之中使用属性,必须写this.属性名
难点:this的指向,在自定义构造函数的this->当前正在创建的对象
预定义构造函数
let obj=bew Object;//空对象
添加:
obj.属性名=属性值
obj.方法名=function(){}
以上两种方式一次只能创建一个
自定义构造函数方式
1、创建自定义构造函数
function 类名(name,age,hobby){
this.name=name;
this.age=age;
this.hobby=hobby;
}
2、调用构造函数创建对象
let obj=new 类名(实参,...)
继承
父对象的成员(属性和方法),子对象可以直接使用
为什么要继承:代码重用!提高代码的复用性
何时继承:只要多个子对象共用的属性和方法,都要集中定义在父对象
1、如何找到原型对象:
1、对象名:__proto__;
2、构造函数:.prototype
2、面试题:两链一包:作用域和原型链和闭包
每个对象都有一个属性__proto__,可以一层一层的找到每个人的父亲,形成一条链式结构,我们称之为原型链,可以找到都对象的成员(属性和方法),
作用:找到共有属性和共有方法,自己没有悄悄往上找
最顶层的是Object的原型,上面有一个toString()所有人都可以使用
继承的笔试题:
1、判断是自有还是共有:
1、判断自有:obj.hasOwnproperty("属性名")
结果为true,则为自有属性,结果为false就是有两种结果,一种是没有,一种是共有
2、判断共有:
if(obj.hasOwnproperty("属性名")==false "属性名" in obj)
//in关键字,会自动地查找整条原型链上的属性,true则是有,false就是没有
}else{ //没有}
完整公式:
if(obj.hasOwnproperty("属性名")){
console.log("自有")
}else{
if("属性名" in obj){
console.log("共有")
}else{
console.log("没有")
}
}
2、修改和删除:自有和共有
自有:
改:obj.属性名=新值
删:delete obj.属性名
共有:**一定要找到原型链进行修改**
改:原型.属性名=新值//不能直接修改,会在本地增加一个同名属性
删:delete 原型.属性名
3、如何为老IE添加indexOf方法(为XX添加XX方法)
if(Array.prototype.indexOf===undefined){
Array.prototype.indexOf=function(key,starti){
starti===undefined&&(starti=0)
for(i=starti;i<this.length;i++){
if(this.[i]==key){
returni
}
}return -1
}
}
4、如何x是不是一个数组:四种方式,不要用typeof,无法查找引用类型
1、判断x是不是继承自Array.prototype
Array.prototype.isPrototype(x)
结果true,false说明不是数组
注:可判断其他类型,把Array换成(Date,RegExp)就行
2、判断x是不是Array这个构造函数创建的
x instanceof Array
同上true为数组,一样可把Array换成其他判断
3、Array.isArray(x) ES-5提供,只能判断数组,不支持其他
4、输出【对象的字符串】形式
在Object上保存着最原始的toString()他的输出结果是:[object 构造函数名]
多态:子对象觉得父对象的成员不好用,就在本地定义了一个同名函数,覆盖了父对象的成员
借用的套路:Object.prototype.toString.call/apply(x)===[object Array]
5、实现自定义的继承:
①两个对象之间继承
子对象.__proto__=父对象
②批量设置继承
构造函数名.prototype=父对象
注:创建对象之前设置好继承关系
Es-6的class关键字:简化面向对象
class 类名 extends 老类{
constructor(name,speed,rl){//constructor里面的就是自有属性
super(name,speed);
this.rl=rl
}
//写上共有方法,没有就会继承老类,也可以自己写,并且不会覆盖到爷爷,就形成了多态
}
3、function:作用域链&闭包
①程序加载时 :
创建执行环境栈(ECS):保存函数的调用顺序的数组
首先压入全局环境(全局EC)
全局EC引用着全局对象window
window保存着我们的全局变量
②定义函数时:
创建函数对象:封装着代码段
在函数对象中有一个scope(作用域)的属性:记录着函数来自的作用域是哪些
全局函数的scope都是window
③调用前:
在执行环境栈(ECS)中压入新的EC(函数EC)
创建出活动对象(AO):保存着本次函数调用时用到的局部变量
在函数的EC中有一个scope chain(作用域链)属性引用着AO
AO还有parent属性是函数的scope引用着的对象
④调用时:
正是因为前三步才带来了变量的使用规则:优先使用局部的,局部没有就找全局的,全局没有就报错
⑤调用完:
函数的EC会出栈,没人引用着AO,AO自动释放,局部变量释放
闭包:希望保护一个可以反复使用的局部变量的一种词法结构,其实还是一个函数,只是写法比较特殊
使用:
①两个函数进行嵌套
②外层函数创建出受保护的变量
③外层函数return出内层函数
④内层函数操作受保护的变量
强调:
①判断是不是闭包,有没有两个函数进行嵌套,返回内层函数,内层函数在操作受保护的变量
②外层函数调用几次就会创建几个闭包,受保护的变量就会多几个副本
③同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
缺点:受保护的变量是不会被释放的,使用过多会内存泄漏-闪退
使用场景:防抖节流
五个事件:
1、elem.onmousemove
2/input.oninput
3、elem.onclick
4、window.onscroll
5、window.onresize
固定公式:
function fdjl(){
var timer=null;
return function(){
if(!=null){
clearTimeout(timer)
}
timer=setTimeout(()=>{
操作
},1000)
}
}
总结:
原型链:每个对象都有一个属性__proto__,可以一层一层的找到每个人的父亲,形成一条链式结构//查询共有属性和方法
作用域链:以函数的EC的scope chain为起点,经过AO逐级引用,形成的链式结构//查找变量,带来了变量的使用规则
闭包:希望保护一个可以反复使用的局部变量//用于防抖节流
ES5-保护对象:保护对象的属性和方法
1、对象的每个属性都有四大方法:
value:xxx//实际保存的值的地方
writable:true//开关,控制着这个属性是否能修改
enumerable:true//开关,是否可以被for in循环
configurable:true//控制这个属性是否可以删除
修改四大属性:
1、Object.defineProperty(对象名,"属性名",{
writable:true/false,
enumerable:true/false,
configurable:true/false
})一次只能保护一个
2、
Object.defineProperties(对象名,{
"属性名":{
四大特性...
}
})只调用一次,不能防止添加
四大特性:其实应该叫做六大特性-可以帮助我们做出动态数据
Object.defineProperty(对象名,"属性名",{
get:()=>{
获取到的数据会被拦截
}
set:(V)=>{
这个v就是拦截的数据,设置的数据会被拦截
}
})
2、对象的深拷贝和浅拷贝
1、浅拷贝:利用按值传递
let obj1={"name":"obj1"}
let obj2=obj1;
2、深拷贝:两者互不影响
let obj1={"name":"obj1"}
let obj2={...obj1}
后端穿衣服:let jsonTxt=JSON.stringify(jsonobj)
前端脱衣服:let jsonobj=JSON.parse(jsonTxt)//eval("("+jsonTxt+")")
Error
目的:快速找到错误;防用户
2、浏览器自带的四种错误类型
语法错误:syntax Error-符号/语法错误
引用错误:ReferenceError-没有创建就在使用
类型错误:Type Error-不是你的方法,你却调用使用了,常见于用undefined和null去操作
范围错误:RangeError-num.toFixed(d)-d只能取值到0-100之间
3、报错也能让后续代码执行
try{
可能出错的代码
}catch(err){
发生错误执行的代码;err-形参,黑色的错误
}
//性能巨差不如用分支结构代替
4、抛出自定义错误:
throw new Error("自定义错误消息")
柯里化函数
function(a){
return function(b){
return function(c){
console.log(a+b+c);
}
}
}
add(3)(5)(7)
匿名函数
①自调:只执行一次,函数中没有用的变量会自动释放,可以用于代替全局代码的写法,绑定好的事件是不会自动释放的
(function(){操作})()
②回调:只要不是自调的匿名函数就是回调函数,一切的回调函数都可以简化成箭头函数
设计模式:
单例模式:也称之为单体模式,保证一个类仅有一个实例对象创建,并且提供了一个访问他的全局访问点:new Vue一个页面一次
做简单的单例:利用ES-6中不允许let重复声明,但是不太推荐:①会污染命名空间②维护不易管控
观察者模式:也称呼订阅-开发模式,是bus总线的底层
事件轮询
1、宏任务:不会卡住单线程应用,可以让后续代码先走
①定时器:setInterval和setTimeout
②AJAX也是一个异步宏任务
2、微任务:ES6提供了Promis对象,可控制异步代码的顺序
function xx(resolve){
setInterval(()=>{
.....
resolve();
},1000)
}
function xx(resolve){
return new Promise(function(resolve)){
setInterval((c)=>{
...
resolve()
},xx)
}
}
new Promise(ajax1).then(ajax).then()...
要想连续执行then要在操作中return Promise,要想执行后面,要加上resolve()放行