Function
作用域:2种
1、全局:随处可用,可以被反复使用,缺陷:容易被污染
2、局部:只能在函数调用时内部可用,不会被污染,缺陷:一次性的,是会自动释放的
*函数的执行原理:
1、程序加载时:
创建执行环境栈(ECS):保存了函数调用的顺序的数组
首先压入全局执行环境(全局EC)
全局EC引用着全局对象window
window中保存着全局变量

2、定义函数时:
创建函数对象:封装代码段
在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
全局函数的scope都是window

3、调用前:
在执行环境栈(ECS)压入一个新的EC(函数的EC)
创建活动对象(AO):保存着本次函数调用时用到的局部变量
在函数中的EC有一个属性scope chain(作用域链)引用AO
AO有一个parent的属性是函数的scope引用着的对象

4、调用时:
正是因为有了前三个步骤,我们才有了变量的使用规则:优先使用局部的,局部没有找全局,全局没有则报错

5、调用完:
函数的EC会出栈,AO无人引用,垃圾回收器登场,AO自动释放,局部变量也就自动释放

*两链一包:
作用域链:以函数的EC为起点,经过AO,【逐级引用】,形成的一条链式结构我们就称之为叫做作用域链
作用:查找变量,带来了变量的使用规则
原型链:今天不管
闭包
*闭包
闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实还是是一个函数
何时:保护一个可以【反复使用的局部变量】
如何使用:
1、两个函数进行嵌套
2、外层函数创建受保护的变量
3、外层函数return出内层函数
4、内层函数要去操作受保护的变量
强调:
1、判断是不是闭包,有没有两层函数嵌套,返回内层函数,内层函数在操作外层受保护的变量
2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

缺陷:
受保护的变量,永远不会被释放,使用过多,会导致内存泄漏
问题:应该在哪里使用?使用场景:防抖节流
应该在哪里使用?使用场景:防抖节流
三个事件需要防抖节流:
1、elem.onmousemove - 频繁的修改DOM树,影响性能
2、input.oninput - 每次input的内容修改都会触发,性能不好
3、window.onresize - 窗口大小触发事件
xxx.以上三个事件=function(){
inner();
}
公式:
function fdjl(){
var timer=null;
return function(){
if(timer!==null){clearTimeout(timer)}
timer=setTimeout(function(){
操作即可!
},1000)
}
}
var inner=fdjl();
防抖节流案例1


防抖节流案例2


*Object
Object:对象 - Array/String/Function/RegExp... 都是前辈们提前创建好的,我们现在要学习的是自定义对象
面向对象:三大特点:封装、继承、多态
面向过程:经过:开始 -> 结束,我们一直的开发方式都是面向过程:先干什么再干什么最后干什么
为什么要面向对象:现实生活中所有的数据都必须包含在一个事物中才有意义
何时要使用面向对象开发方式:以后做任何操作都要封装在一个对象中 - 非常的不适合初学者
笔试题
1、*鄙视题:简单的说一说 面向对象 和 面向过程 开发方式的区别?
面向对象:对象(属性和方法),js有一句话万物皆对象,假设一个人是一个对象的话
属性:身高、体重、姓名、性别、年龄、智商、情商、发色...
方法:吃饭、睡觉、拉屎、跑步、喝水、唱歌...
所有的东西都要放在一个对象之中,才显得更有意义
面向过程:经过:开始 -> 结束,我们一直的开发方式都是面向过程:先干什么再干什么最后干什么
封装:创建自定义对象:3种方式
1、*直接量:
var obj={
"属性名":属性值,
...
"方法名":function(){操作},
...
};
特殊:
1、其实属性名和方法名的""可以不加的,暂时不推荐,因为以后我们要学习一种数据格式JSON,要求属性名和方法名必须是一个"",单引号都不可以,为了习惯,我们就一直加上使用
2、访问对象的属性和方法
*obj.属性名 === obj["属性名"]
*obj.方法名() === obj["方法名"]();
***js有一句话万物皆对象,一切对象的底层都是hash数组
3、访问到不存在的属性,返回undefined
4、可以随时随地的添加新属性和方法
5、希望遍历出对象所有的东西,使用for in循环
6、***如果你希望再对象的方法里使用对象自己的属性:this.属性名
*****难点:this的指向
1、单个元素绑定事件:this->这个元素
2、多个元素绑定事件:this->当前触发的元素
3、函数中使用this:this->当前调用此函数的对象,看看函数前面是谁
4、定时器中this->window
5、箭头函数this->外部对象
6、构造函数中的this->当前正在创建的对象
2、预定义构造函数方式
预定义构造函数方式:var obj=new Object();
obj.属性名=属性值;
obj.方法名=function(){}
以上两个方法预定义构造函数方式和直接量都有一个缺陷:一次只能创建一个对象
3、自定义构造函数:批量创建
批量创建对象:【自定义】构造函数方式
1、创建自定义构造函数
function 类名/构造函数名(形参1,形参2,...){
this.属性名1=形参1
this.属性名2=形参2
}
2、调用构造函数创建出对象
var obj1=new 构造函数名(实参1,实参2,...)
var obj2=new 构造函数名(实参1,实参2,...)
封装面向对象选项卡

面向对象:优缺点
面向对象
优点:
1、逼格高,所有的属性和方法都保存在一个对象之中 - 更符合现实生活
2、每个功能特地分开写 - 便于后期维护,哪怕没有注释,我也能一眼看懂代码
3、铁锁链舟 - 一个方法触发多个方法联动
缺点:对新手不友好,this的指向变来变去的