js函数的相关问题及补充

前言

除了在前面所学习的javascript函数的基础部分内容,js函数还有许多内容需要深入了解,以下内容是对博主练习时的遇到相应的问题及对js函数部分补充,如有错误,欢迎大家给予指正。

一、函数的解析问题

首先,观察以下案例

var a=1;
function fn(){
	a=10;
}
fn();
console.log(a); // 10
var a=1;
function fn(a){
	a=10;
}
fn(a);
console.log(a); // 1
var a=1;
function fn(){
	var a=10;
}
fn();
console.log(a); // 1

第一个案例中,运行函数之前a已经赋值为1,运行函数时,在函数中寻找变量a,最终找到全局变量a,将a赋值为10,所以最终打印出的a的值为10,具体解析为

var a; //a的值为undefined
function fn(){
	a=10; //寻找变量a,最终在函数外部找到全局变量a,对全局变量a进行赋值
}
a=1; //a被赋值为1
fn(); //运行函数,a被赋值为10
console.log(a); // 10

第二个案例中,参数传入时是进行了栈中值的复制,函数中运行的是a的复制a’,a的值没有发生改变,具体解析如下

var a; //a的值为undefined
function fn(a){  //进行a的复制a',值为undefined
	a=10; //a'赋值为10
}
a=1; //a被赋值为1
fn(a); //将参数a传入函数,传入的a的值为1
console.log(a); // a的值为1

第三个案例中,函数内部定义了局部变量a,运行函数时,函数优先在内部寻找局部变量,找到局部变量后直接对局部变量赋值,不会再去外部寻找全局变量,在运行函数后,没有被标记的局部变量被内存回收,最终打印的是全局变量a的值,解析如下

var a; //定义全局变量a   值为undefined
function fn(){ 
	var a; //定义局部变量a   值为undefined
	a=10; //局部变量a被赋值为10
}
a=1; //全局变量a被赋值为1
fn(); //运行函数,局部变量被内存回收
console.log(a); // 打印的a为全局变量,值为1

总结:

  • 函数在预解析具有函数提升的效果
  • 函数使用变量作为参数时,是对变量进行复制后传入函数的,函数中参数的变化不会影响到原本的变量
  • 函数进行内部变量赋值时优先从内部寻找局部变量,找到局部变量后直接对局部变量进行赋值,如果没有找到局部变量,就从函数外部寻找变量,直到找到全局变量为止

二、循环内部函数运行问题

案例:设置3个按钮,每按一个按钮显示当前按钮的索引弹窗。

var btns=document.getElementsByClassName("btns");
for (var i=0;i<btns.length;i++){
    btns[i].onclick=function(){
        alert(i+1);
    }
}

按照上述代码运行的结果是,依次点击按钮,每次弹窗弹出的都是4,说明函数运行时,循环已经结束,函数内部 i 的值为循环结束时的3

改进方法一:
将循环每次运行的 i 值保存在对象的一个属性内

 var btns=document.getElementsByClassName("btns");
for (var i=0;i<btns.length;i++){
    btns[i].index=i;//将每次循环的i保存给每个按钮的属性中
    btns[i].onclick=function(){
        alert(this.index+1);//使用this指向当前的对象btns[i]
    }
}

改进方法二:
定义一个必包函数,将其函数体本身作为返回值返回

 var btns=document.getElementsByClassName("btns");
for (var i=0;i<btns.length;i++){  
    btns[i].onclick=function(num){
        return function(){   //必包函数作为返回值返回
            alert(num+1);   
        }
    }(i);
} 

必包函数优缺点:
优点:可以访问到函数内部的局部变量
缺点:必包函数的作用域被延长了,造成内存使用变大,并有可能造成内存泄漏

改进方法三:
使用let声明循环中变量,其基本效果同var一致

var btns=document.getElementsByClassName("btns");
for (let i=0;i<btns.length;i++){
    btns[i].onclick=function(){
        alert(i+1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值