1、*****Function
***作用域:
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中的scope chain属性为起点,经过AO,逐级引用,形成的一条链式结构,就称之为叫做作用域链
作用:变量的使用规则,查找变量
*****闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样
何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:4步
1、两个函数相互嵌套
2、外层函数创建出受保护的变量
3、外层函数要return返回内层函数
4、内层函数要操作受保护的变量
强调:
1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏
使用场景:防抖节流 - 有三个事件需要做防抖节流:执行的速度非常的快,减少DOM树的渲染
1、elem.onmousemove - 鼠标移动事件
2、input.oninput - 输入内容有变化就会触发
3、window.onresize - 当前窗口的尺寸如果发生了变化就会触发:JS版本的媒体查询
公式:
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...对象具有属性和方法,都是预定义好,现在我们学习自定义对象
2、*****面向对象:Object:三大特点:封装、继承、多态
1、***开发方式:
面向过程:经过 - 开始->结束,其实我们一直以来的开发方式都是面向过程:先干什么再干什么最后干什么
面向对象:对象(属性和方法),js有一句话万物皆对象,假设一个人是一个对象的话:
属性:姓名、性别、身高、体重、爱好、智商...
方法:吃饭、睡觉、拉粑粑、跑步、走路、打字、说话...
为什么要面向对象:现实生活中所有的数据都要保存在一个事物中才有意义
何时使用面向对象:以后做任何操作都要封装在一个对象中 - 建议:不太适合初学者
2、封装对象:创建自定义对象:3种
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、***函数中使用this:this->谁在调用此方法,this指向就是谁
4、定时器this->window
5、箭头函数this->外部对象
2、预定义构造函数方式:
var obj=new Object();//空对象
//需要自己后续添加属性和方法
obj.属性名="属性值";
obj.方法名=function(){}
以上两种方法创建都有一个缺陷:一次只能创建一个对象,适合创建单个对象的时候使用(第一种方式)
3、自定义构造函数方式:- 何时创建多个对象:2步
1、创建自定义构造函数
function 类名(name,age,salary){
this.name=name;
this.age=age;
this.salary=salary;
}
2、反复调用自定义构造函数创建出对象
var xxx=new 类名("实参",...)
面向对象:
优点:1、逼格高,所有的属性和方法都是保存在一个对象之中 -更符合现实生活:代码风格、代码速度
2、每个功能特地的分开写 - 便于维护
3、铁锁连舟 - 一个方法触发多个方法联动
缺点:1、对新手不友好 - this的指向
ECMAscript - 核心语法1 - 掘金 (juejin.cn)
ECMAscript - 核心语法2 - 掘金 (juejin.cn)
ECAM script - 核心语法3 - 掘金 (juejin.cn)
ECMA script - 核心语法4-1 - 掘金 (juejin.cn)
ECAM script - 核心语法4-2 - 掘金 (juejin.cn)
ECMA script - 核心语法5 - 掘金 (juejin.cn)
ECMA script - 核心语法6 - 掘金 (juejin.cn)
ECMA script - 核心语法7-1 - 掘金 (juejin.cn)
ECMAscript 8 - 掘金 (juejin.cn)
ES5&ES6 - 掘金 (juejin.cn)