高级 JavaScript #function #hoist # overload #匿名函数 #作用域 #作用域链 #闭包

function

1. 用声明方式创建: 
	(1). function 函数名(形参变量列表){
			函数体;
			return 返回值
		}
	(2). 问题: 会被声明提前——破坏程序正常的执行顺序
2. 用赋值方式创建: 
	(1). var  函数名=function(形参变量列表){
			函数体;
			return 返回值
		}
	(2). 好处: 除了不会被声明提前之外,其余用法与普通函数完全一样!
3.new来创建: 
	(1). var 函数名=new Function("形参1","形参2",...,"函数体;return 返回值");
	(2). 虽然用的少,却揭露了本质:
	a. 一切函数都是一个保存代码段的引用类型的对象
	b. 函数名仅仅是一个普通的变量而已
	c. 函数名变量通过函数对象地址引用着函数对象
	d. 调用函数时,都是通过函数名中的地址找到函数对象,执行对象中保存的代码段内容

声明提前hoist:

1.在程序开始执行前,JS引擎会扫描程序中的varfunction,提前到当前作用域的顶部集中创建
2.=号赋值会留在原地
存在的问题:会破坏程序的顺序执行

重载overload:

1.相同函数名,不同形参,调用时,可以根据传入的实参不同,动态选择函数来调用
2.如何实现重载:不要定义任何形参,arguments:函数中自带,类数组对象,判断个数
//示例:可以根据提供不同的形参值来选择对应的支付方式
 function pay(){
     if(arguments.length==0){
         alert("手机支付")
     }else if(arguments.length==1){
         alert("现金支付")
     }else if(arguments.length==2){
         alert("刷卡")
      }
    }
 pay()

匿名函数:

1.使用原因:节约内存,用完被释放,防止污染全局
2.使用场景:回调函数,JS程序包裹在匿名函数自调用中
//示例:
(function(){
   var star=new Date();
     alert(`开始加载页面内容 ${star.toLocaleString()}`)
   var end=new Date(); //局部变量
      alert(`页面内容加载完成,at:${end.toLocaleString()}`);
})()
console.log(start);//报错: start is not defined
console.log(end);//报错: end is not defined

作用域

1.用途:一个变量的可用范围
2.本质:也是一个专门保存变量的对象

全局作用域:
保存全局变量的作用域,本质是window对象,反复使用一个变量都能使用时,都将变量创建在全局范围内,可以反复使用,容易被污染;

函数作用域:
保存只能在函数内使用的局部变量的对象,仅在函数内使用,不可重用,只有在调用函数时才临时创建,不会被污染,但不可重用;

记住一重要的问题:函数不调用,代码不执行,不要轻视这句话

作用域的简单示例
var a=10;  
function fun(){   //只是创建函数,没有调用
  var a=100;      //函数范围内自己的变量
  a++;            //改变作用域内a的值
  console.log(a)  //101 //所以输出101
}
fun();            //调用时,执行函数内容
console.log(a)  //10  

var b=10;  
function fun(){
	b=100;  //不是创建变量,只是把100存在全局的b中,因为没有自己的var
	b++;    //在全局变量的b上执行++
	console.log(b); //101 自己没有b变量 输出全局的b
}
fun();  
console.log(b)  //函数内部的语句改变了全局变量的值,所以最后输出101

函数的执行过程

1.定义函数时:会创建函数对象,保存内容,每个函数对象都会有一个好友列表
2.调用函数时:
	(1).先创建本次函数调用的函数作用域对象
	(2).创建函数所需要的局部变量(var ,形参)
	(3).在函数对象中保存执行语句,操作变量
	(4).只要函数作用域中有要用的局部变量,就优先在函数作用域中查找使用
    (5).除非函数作用域中没有要用的局部变量,才被迫去全局查找变量使用

JS中没有块,局部作用域

1.if,elseif,else,while,dowhile,switch case,for{}都不是作用域
2.这些{}中的变量,出了{},依然可以使用!
3.比如: 
	var h=new Date().getHours();
	if(h<12){
   		var a="上午";
	}else{
   		var a="下午";
	}
	console.log("现在是:"+a);

作用域链

1.每个函数对象身上带的,保存这个函数可以访问的所有作用域的集合
2.作用域链保存了一个函数可用的所有变量
3.控制变量的使用顺序:就近
 
var b=10;
function fn(){
	b=100;
	b++;
	console.log(b);
}
如果作用域中有要用的变量,优先使用作用域内的变量,如果没有,就去全局查找                             

闭包

首先无论全局变量还是局部变量都有不可兼得的优缺点
全局:优点可以反复使用,缺点随处可用,污染
局部:优点仅函数内部使用,缺点不能反复使用

既反复使用一个变量,又保护变量不被污染  使用闭包

用途:闭包反复使用变量,又不会被污染全局
本质:外层函数的作用域对象,被内层函数的作用域链引用着,无法释放,形成闭包

function parent(){ //1.外层函数包裹要保护的变量和内层函数;
	var total=1000;   //total此时已经变成了局部函数;
	return function(money){  //把外部想用的内层函数return到外层函数的外部 
		total-=money;        
		alert(`花了${money}元,还剩${total}元`)
	}
}
var pay=parent();  //向使用内层函数需要调用外层函数,才能获得return出来的对象,保存在变量中反复使用
pay(100)

闭包原理


 1. 外层函数调用后,由于外层函数的作用域对象被内层函数引用着,无法释放,就形成了闭包

闭包缺点

缺点:引用闭包的内层函数,比普通的函数多占用一块内存 多占的是外层函数的作用域对象
解决:如果闭包不再使用,应该尽快释放,保存内层函数的变量=null;

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值