ECMA script - 核心语法7-2

194 阅读5分钟

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自动释放,所以局部变量也就释放了
          

函数的执行原理:

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

 *****闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样
何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:41、两个函数相互嵌套
	2、外层函数创建出受保护的变量
	3、外层函数要return返回内层函数
	4、内层函数要操作受保护的变量

强调:
   1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
   2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
   3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏
使用场景:防抖节流 - 有三个事件需要做防抖节流:执行的速度非常的快,减少DOM树的渲染
	1、elem.onmousemove - 鼠标移动事件
	2、input.oninput            - 输入内容有变化就会触发
	3window.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、封装对象:创建自定义对象:31、直接量方式:
		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、定时器this->window
					5、箭头函数this->外部对象

	2、预定义构造函数方式:
		var obj=new Object();//空对象
		//需要自己后续添加属性和方法
		obj.属性名="属性值";
		obj.方法名=function(){}

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

	3、自定义构造函数方式:- 何时创建多个对象:21、创建自定义构造函数
			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)