第三周Day6

129 阅读5分钟

Function作用域:

1.全局作用域:随处可用,可以反复使用 缺点:容易被污染;

2.局部作用域:只能在函数被调用时内部可用,不会被污染, 缺点:一次性的,会自动释放;

函数的执行原理:

1、程序加载时:

创建执行环境时(ECS) -> 保存函数调用顺序的数组;
首先压入全局执行环境(全局EC);
全局EC引用着全局对象window
window中保存着全局变量;

2.定义函数时:

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

3.调用前:

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

4.调用时:

正式因为有了前三个步骤,我们才有了变量的使用规则 -> 优先使用局部的,局部没有使用全局的,全局没有就报错;

5.调用完:

函数的EC会出栈,没人引用AO,AO会自动释放,所以局部变量也就释放了。

两链一包:

作用域链:

以函数的EC中的scope chain属性为起点,经过AO,逐级引用,形成了一条链式结构,就称之为叫做作用域链;
作用:变量的使用规则,查找变量;

闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样;

何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:41.两个函数相互嵌套
    2.外层函数创建出受保护的变量
    3.外层函数要return返回的内层函数
    4.内层函数要操作受保护的变量
强调:
    1.判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量;
    2.外层函数调用了几次,就创建了几个闭包,受保护得变量就有了几个副本;
    3.同义词外层函数调用,返回得内层函数,都是在操作同一个受保护得变量;
缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏;

使用场景:防抖节流

有三个事件做防抖节流,实行的速度非常快,减少DOM树的渲染

1.elem.onmousemove 	鼠标移动事件
2.input.oninput	      	输入框内容有变化时会触发
3.window.onresize	当前窗口的尺寸发生了变化时就会触发;
公式:
elem.on事件名=function(){
                inner();
            }
function fdjl(){
var timer=null;//1 2 3 - 定时器序号
return function(){
if(timer){clearTimeout(timer);timer=null}
timer=setTimeout(function(){
            //操作
        },1000)
    }
}		
var inner=fdjl();

对象:

Array/String/Function/Math...对象具有属性和方法,都是预定义好的

现在学习自定义对象:

面对对象:Object:三大特点:封装,继承,多态

1.开发方式:

面向过程:开始 -> 结束  我们一直以来的开发方式都是面向过程:先干什么在干什么最后干什么
面向对象:对象(属性和方法),js有一句话万物皆对象,假设一个人是一个对象的话;
    属性:姓名,性别,身高,体重,爱好。。。
    方法:吃法,睡觉,拉粑粑,跑步,拳击,打游戏。。。
为什么要面向对象:现实生活中所有的数据都要保存到一个事务中才有意义;
何时使用面向对象:以后做任何操作都要封装在一个对象中 - 只是建议 ; 对新手不太友好

2.封装对象:创建自定义对象:三种

1.直接量方式:
    var obj={
    "属性名":"属性值",
    ...
    "方法名":function(){},
    ...
    }
强调:
1.其实属性名和方法名的引号可以省略不写,但是建议暂时写上,因为后续要学习JSON数据格式,要求必须加上""
2.访问对象的属性和方法:
    对象名.属性名	===	对象名["属性名"]
    对象名.方法名	===	对象名["方法名"]();
    JS中的一切对象的底层都是hash数组
3.访问到不存在的属性或者方法时会返回undefined
4.可以后期随时随地的添加新属性和新事件
5.如果希望遍历出对象中的所有东西
    for(var i in 对象名){
        对象名[i]
    }
6.如果你希望在对象的额【方法】中使用对象自己的属性:写为this.属性名
难点:this的指向:
    1.单个元素绑定事件: this -> 这个元素
    2.多个元素绑定事件: this -> 当前触发事件的元素
    3.函数中使用thisthis -> 谁在调用此方法.this就指向谁
    4.定时器thisthis -> window
    5.箭头函数thisthis -> 外部对象

2,预定义构造函数方式:

var obj=new Object(); 创建出一个空对象
需要自己后续添加属性和方法
    obj.属性名="属性值";
    obj.方法名=function(){}

以上两种方法创建都有一个缺陷:一次只能创建一个对象,适合创建单个对象的时候使用(第一种方式)

3,自定义构造函数方式:

1,创建自定义构造函数:
function 类名(name,age,salary){
    this.name=name;
    this.age=age;
    this.salary=salary;
}
2,反复调用自定义构造函数创建出对象
    var xxx=new 类名("实参",.....)

面向对象:

优点:

1.逼格高,所有的属性和方法都是保存在一个对象之中  --- 更符合生活:代码风格,代码速度都凸显逼格
2.每个功能特地的分开写  --- 便于维护
3.链式反应 --- 一个方法触发多个方法联动

缺点:

对新手的不友好   ---   this 的指向;