animate.css和swiper插件
1、animate.css
含义:是一个动画库,里面放着很多的动画,方便我们程序员使用
如何使用:
1、上网搜索animate.css
2、下载
3、将此文件引入到项目中
4、挑选喜欢的动画,把class放到那个元素上
5、放上class以后设置上animate-duration:3s;执行时长
6、还要根据不同的动画,设置不同的初始效果,才会更好看
2、swiper插件:
作用:专门的一个轮播插件,提供了html/css/js直接复制即可
面向对象开发:
1、Object:
1、js中万物皆对象,同时js也是基于原型的面向对象语言
2、对象具有属性和方法,都是用于定义好的,我们也可以自定义
3、面向对象有三大特点:封装、继承和多态
1、开发方面:
面向过程开发:开始——>结束,之前学的开发方式都是面向过程的,先干什么后干什么
面向对象:对象(属性和方法)
何时面向对象:以后任何一个操作都要封装在一个对象中,新手不推荐,难度大
为什么要用面向对象开发:现实生活中的所有数据都必须包含在一个事物之中才有意义
2、封装/创建/定义 对象3种
1、直接量方式:
var obj ={
"属性名":"属性值",
......
"方法名":function(){操作}
}
强调:
1、其实属性名和方法名的""可以省略不写,但是不建议,因为在后期JSON格式中必须要加上
2、访问对象的属性和方法:
obj.属性名;===obj["属性名"];
obj.方法名;===obj["方法名"]();
js中除了undefined和null,其余一切数据的底层都是哈希数组
3、访问到不存在的属性,返回undefined
4、可以随时添加新属性和新方法:
obj.属性名=新值;
obj.方法名=function(){}
5、使用for in 遍历以后拿到所有东西,obj[i]才能拿到对应的值
6、如果希望在对象的方法里使用自己对象的方法,写为this.属性名
难点:this的指向:
1、单个元素绑定事件:this指向这个元素
2、多个元素绑定事件:this指向当前触发事件的元素
3、定时器中的this指向window
4、箭头函数中的this指向外部对象
5、函数中的this指向当前在调用此函数的那个对象
6、构造函数中的this指向当前正在创建的对象
2、预定义构造函数:
var obj=new Object();//空对象
以上两种创建对象的方式都有一个缺陷:一次只能创建一个对象,适合在创建单个对象的时候使用第一种方法,批量创建对象选择以下这个方法
3、自定义构造函数方式:2步
1、创建自定义构造函数:
function 类名(name,age,hobby){
this.name=name;
this.age=age;
this.hobby=hobby;
}
千万不要在里面创建方法,否则的话每个对象都会创建出来一个相同的方法,浪费内存,学习了继承以后可以解决这个问题
2、调用构造函数创建对象:
var obj=new 类名(实参,...);
面向对象的优点:
1、逼格高,所有的属性和方法都保存在一个对象之中,更符合现实更有意义
2、每个功能特地分开写——以便于后期的维护
3、铁索连舟——一个方法触发多个方法联动
2、继承:父对象的成员(属性和方法),子对象可以直接使用
为什么要继承:代码重用,提高代码的复用性,节约了内存空间,提升了网站的性能
何时继承:只要多个字对象公用的属性和方法,都要集中定义在父对象之中
1、如何找到原型对象(父对象):
1、对象名.__proto__//必须要先有一个对象
2、构造函数名.prototype;//构造函数名几乎人人都有,除了Math和window
new 构造函数名();Array,String,Date...
2、面试题:两链一包:作用域链、原型链、闭包
原型链:
每个对象都有一个属性__proto__,可以一层一层的找到每个人的父亲,形成的链式结构就是原型链
它可以找到父对象的成员(属性和方法),作用:找到共有属性和方法
最顶层是Object的原型,上面有一个我们熟悉的toString方法,怪不得人人都可以用toString方法
3、有了原型对象,可以设置共有属性和方法
4、继承中的笔试题:
1、判断公有还是自有:
1、判断自有:obj.hasOwnPropety("属性名");如果结果为true则为自有
obj.hasOwnPropety("属性名");
2、判断公有:if(obj.hasOwnPropety("属性名")===false&&"属性名" in obj) 此处的in是一个关键字,会自动查找整条原型链上的属性
if(obj.hasOwnPropety("属性名")===false&&"属性名" in obj){
公有
}else{
自有
}
判断自有还是公有的完整公式:
if(obj.hasOwnPropety("属性名")){
自有
}else{
if("属性名" in obj){
公有
}else{
没有
}
}
2、修改和删除:自有和公有
修改:
自有:obj.属性名=新值;
公有:原型对象.属性名=新值;
删除:
自有:delete obj.属性名;
公有:delete 原型对象.属性名;
3、如何为老IE的数组添加indexOf方法:
if(Array.prototype.indexOf===undefined){
Array.prototype.indexOf=function(key,starti){
if(starti===undefined){
starti=0;
}
for(var i=starti;i<this.length;i++){
if(this[i]==key){
return i;
}
}
return -1;
}
}
arr.indexOf();
4、判断X是不是一个数组:4种方法,千万不能用typeof方法,此方法只能检查原始类型,不能检查一用类型,返回的是一个Object
1、判断X是不是继承自Array.prototype:
Array.prototype.isPrototypeOf(X);
=>返回为true则是一个数组
2、判断X是不是由Array这个构造函数创建
X.instanceof Array
3、Array.isArray(X)
Array.isArray(X)//只有数组能用这个方法
4、输出[对象字符串格式]的方式
在Object的原型上有一个最原始的toString的方法
原始toString的输出方式:[object 构造函数名]
多态:同一个方法,不同的人使用有不同的效果,它有多种形态
固定套路:
Object.prototype.toString.call/replay(X)===>[object Array]
5、实现自定义继承:
1、两个对象之间设置继承:
子对象.__proto__=父对象
2、多个对象之间设置继承:
构造函数名.prototype=父对象;
此方法要掌握好时机,设置好继承关系后才能创建对象
2、class关键字:简化面向对象(封装、继承、多态)
语法:
class 类名 extends 老类类名{
constructor(name,age,hobby){//自有属性放在constructor中
supper(name,age);//此处放的是老类中的公有属性
this.hobby=hobby;//添加一身多于老类的属性
}
公有方法//constructor外放的是公有方法,亦可以自己新建
}
3、****闭包****
1、作用域:2种
1、全局:随处可用,可以反复使用。缺点:容易被污染。
2、函数:只能在函数中调用,不会被污染。缺点:一次性的,是会自动释放的
函数的执行原理:
1、函数加载时:
创建执行环境栈(ESC):保存函数的调用顺序的数组
首先压入全局执行原理(全局EC)
全局EC引用着全局对象window
window中保存着我们的全局变量
2、定义函数时:
创建函数对象:封装代码段
在函数对象之中有一个scope(作用域)属性:记录着我们函数自己的作用域是哪里
全局函数的scope都是window
3、调用前:
在执行环境栈(ESC)中压入新的EC(函数的EC)
创建出活动对象(AO):保存着本次函数调用时用到的局部变量
在函数的EC中有一个scope chan(作用域链)属性引用着AO
AO有一个parent属性是函数的scope引用着的对象
4、调用时:
正是因为前面3步,才带来了变量的使用规则:优先使用自己的,自己没有找全局。全剧没有就报错
5、调用完:
函数的EC会出栈,没人引用AO,AO会自动释放,局部变量也就释放了
**闭包**:希望保护一个可以反复使用的变量的时候
如何使用:
1、两个函数进行嵌套
2、外层函数创建出需要保护的变量
3、外层函数return出内层函数
4、内层函数再操作受保护的变量
强调:
1、判断是不是闭包:有没有两个函数嵌套,外层函数返回内层函数,内层函数操作着受保护的变量
2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有几个副本
3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
缺点:受保护的变量,永远都不会被释放,使用过多,会导致内存泄漏——不可多用
问题:使用场景:——防抖节流
三个事件:
1、鼠标移动事件:elem.onmousemove
2、input输入方法:input.oninput
3、窗口大小更改事件:onresize
防抖节流的公式:
function fdjl(){
var timer=null;
return function(){
if(clearTimeout(timer);timer=null){
timer=setTimeout(()=>{
操作;
},500)
}
}
}
总结:两链一包:
1、作用域链:以函数的EC的spoce chain属性为起点,经过AO,逐级引用,形成一条链式结构,我们称之为作用域链
作用:查找变量,带来了变量的使用规则:优先使用自己的,自己没有找全局要,全局没有就报错
2、原型链:每个对象都有一个属性叫做.proto,可以一层一层的找到每个对象的原型对象,最顶层的就是Object的原型,形成一条链式结构,我们称之为原型链
作用:查找属性和方法,哪怕自己没有也会顺着原型链向上找,之所以人人都能用toString方法,就是因为它在最顶层
3、闭包:希望保护一个可以反复使用的局部变量的一种词法结构,其实是一个写法较为特殊的函数
作用:专门用于防抖节流