animate.css动画库
使用步骤:
- 下载
- 引入animate.css
- 把class放在需要动画的元素上
- 设置animation-duration执行时间,自身提供class:animate__animated只能为1秒
swiper插件(轮播插件)
- 下载插件包
- 引入js和css
- 复制需要的轮播代码
运动(动画)函数
function animate(selector,obj){
var elem=document.querySelector(selector);
for(var i in obj){
console.log(i)
elem.style[i]=obj[i];
}
}
高德/百度地图
- 搜索百度/高德地图开放平台
- 应用管理->我的应用->创建应用->应用名称随意->应用类型选择浏览器端->白名单:0.0.0.0/0
- 开发文档,JavaScriptAPI->示例DEMO->挑选你喜欢的地图,复制到你的项目之中
- 修改CSS/JS代码,查询在线的经纬度(百度地图拾取坐标系统)
注意: 地图可以混搭使用,但是再某次升级过后,出现了GL地图和普通版地图,两者不可以混搭使用,只有GL和GL混搭,普通版和普通版混搭
封装自定义对象
直接量方式
var obj={
'属性名':'属性值',
'方法名':function(){操作},
}
- 属性名和方法名可以不加''和""
- 访问对象属性和方法
-
对象名.属性名 <-->对象名['属性名']
-
对象名.方法名() <-->对象名['方法名']()
- 访问不存在的属性返回undefined
- 添加新属性和方法
-
obj.属性名=属性值
-
obj.方法名=function(){}
- 遍历对象,使用for in循环
- 在对象里面使用对象自己的属性,必须this.属性名
this的指向
- 单个元素绑定事件this-->这个元素
- 多个元素绑定事件this-->当前元素
- 定时器this-->window
- 箭头函数this-->外部对象
- 函数中this-->谁在调用,this就是谁
- 自定义构造函数this-->正在创建的对象
预定义构造函数
var obj=new Object();//空对象
obj.属性名=属性值;
obj.方法名=function(){}
自定义构造函数
//创建自定义构造函数
function 类名(name,age,hobby){
this.name=name;
this.age=age;
this.hobby=hobby;
}
//调用构造函数创建对象
var obj=new 类名(实参,)
继承
找原型对象
对象名.__proto__;//必须要先有一个对象构造函数名.prototype//构造函数人人都有除了Math和Window,new 构造函数名()
设置共有属性和共有方法
原型对象.属性名=属性值;原型对象.方法名=function(){}
原型链
每个对象都有一个属性__proto__可以一层一层的找到父类,形成链式结构,叫原型链
判断自有还是共有
- 判断自有
pbj.hasOwnProperty('属性名') - 判断共有
if(obj.hasOwnProperty("属性名")){
console.log("自有")
}else{
if("属性名" in obj){
console.log("共有");
}else{
console.log("没有");
}
}
修改和删除:自有和共有
- 自有
-
- 修改
obj.属性名=新值
- 修改
-
- 删除
delete obj.属性名
- 删除
- 共有
-
- 修改
原型.属性名=新值
- 修改
-
- 删除
delete 原型.属性名
- 删除
判断是不是数组
判断x是不是继承自Array.prototype
Array.prototype.isPrototypeOf(x);
结果为true,说明是数组,结果为false,说明不是数组
判断x是不是由Array这个构造函数创建的
x instanceof Array
结果为true,说明是数组,结果为false,说明不是数组
Array.isArray(x) - 老IE不支持,只有数组有此操作
结果为true,说明是数组,结果为false,说明不是数组
*输出【对象的字符串】形式
在Object的原型上保存着最原始的toString();
最原始的toString()输出的形式:[object 构造函数名]
实现自定义继承
- 两个对象之间设置继承
子对象.__proto__=父对象 - 批量设置继承:
构造函数名.prototype=父对象 -
- 注意时机:应该在创建对象之前设置好继承关系
class关键字 - Es6简化面向对象(封装、继承、多态)
class 类名 extends 老类{
constructor(name,speed,rl){//写在constructor里面的其实就是自有属性
super(name,speed);
this.rl=rl;
}
//共有方法放在老类
function 方法名(){}
}
作用域链
- 全局:随处可用,可以反复使用。缺点:容易被污染
- 函数:只能在函数内部可用,不会被污染。缺点:一次性的,使用完就会释放
执行原理
程序加载时
- 创建执行环境栈(ECS):保存函数调用顺序的数组
- 压入全局执行环境(全局EC)
- 全局EC引用着全局对象window
- window中保存着我们的全局变量
定义函数时
- 创建函数对象:封装代码段
- 在函数对象中有一个scope(作用域)的属性:记录函数来自的作用域
- 全局函数的scope都是window
调用前
- 在执行环境栈(ECS)中压入新的EC(函数的EC)
- 创建出活动对象(AD):保存着本次函数调用时的局部变量
- 在函数的EC中有一个scope chain(作业域链)属性引用着AO
- AO还有parent属性时函数的scope引用着的对象
调用时
变量使用规则:先使用局部,局部没有找全局,全局没有报错
调用完
函数的EC会出栈,没人引用着AO,AO自动释放,局部变量也释放
闭包(保护一个可以反复使用的局部变量)
- 两个函数进行嵌套
- 外层函数创建出受保护的变量
- 外层函数return出内层函数
- 内层函数操作受保护的变量
注意:用一次外层函数调用,返回的内层函数都是操作同一个受保护的变量
缺点:受保护的变量,永远不会被释放,使用过多会导致内存泄漏
使用场景:防抖节流(触发的飞快,飞快的修改DOM树)
elem.onmousemoveinput.oninputelem.onclickwindow.onscrollwindow.onresize
function 方法名(){
var timer=null;
return function(){
if(timer!=null){
clearTimeout(timer)
}
timer=setTimeout(()=>{
操作
},1000)
}
}
保护对象的属性和方法
对象每个属性都具有四大特性
{
value:值l;//保存值的地方
writable:true/false,//控制属性是否被修改,默认true
enumerable:true/false,//控制属性是否被循环遍历到,默认true
configurable:true/false,//控制属性是否被删除,默认true
}
修改四大特性
Object.definProperty(对象名,'属性名',{四大特性})一次只能保护一个属性的四大特性Object.defineProperties(对象名,{'属性名':{四大特性},....})一次可以保护多个属性
三个级别
- 防添加
Object.preventExtensions(x) - 防添加和删除
Object.seal(x) - 防添加和删除和修改
Object.freeze(x)
Object.defineProperty(对象名,"属性名",{
get:()=>{
console.log("获取数据会进行拦截")
},
set:(v)=>{
//v就是你设置的东西
console.log("设置数据会进行拦截")
}
})
对象的深拷贝和浅拷贝
- 浅拷贝(按值传递)
var obj1={'name':'ob'}
var obj2=obj1;
- 深拷贝:两者互不影响
//第一种方法
var obj1={'name':'obj'}
var obj2={...obj1}
//第二种方法
var obj2=JSON.parse(obj2)
//第三种方法
var obj2=eval('('+obj2+')')
Error对象(错误)
错误类型
- 语法错误:
SyntaxError- 一定是你的符号/语法写错了 - 引用错误:
ReferenceError- 没有创建就去使用了 - 类型错误:
TypeError- 不是你的方法,你却去使用了,最有可能的就是你拿到了undefined和null - 范围错误:
RangeError- 只有API会遇到:num.toFixed(d);//d取值范围:0~100之间
错误处理
try{
//可能报错的代码
}catch(err){
//发生错误执行的代码
}
try...catch...性能差,可以用分支结构代替
自定义错误:报错就不会执行后续代码
`throw new Error('自定义错误信息')
柯里化函数
function add(a){
return function(b){
return function(c){
console.log(a+b+c);
}
}
}
add(3)(5)(7)
匿名函数
- 自调
(function(){操作})() - 回调
elem.on事件名=function(){}
事件轮询
宏任务
- 定时器:setInterval 和 setTimeout
- AJAX - 他是前端和后端连接的关键点,他也是一个异步宏任务
微任务
function ajax1(resolve){
setTimeout(()=>{
console.log("<h1>页面的头部</h1>");
resolve();//放行函数
},Math.random()*5000);
}
function ajax2(){
return new Promise(function(resolve){
setTimeout(()=>{
console.log("<h1>页面的身体</h1>");
resolve();
},Math.random()*5000);
})
}
function ajax3(){
return new Promise(function(resolve){
setTimeout(()=>{
console.log("<h1>页面的脚部</h1>");
resolve();
},Math.random()*5000);
})
}
new Promise(ajax1).then(ajax2).then(ajax3);