Javascript知识分享

最近在读大叔译的javascript编程精解这本书,确实是本好书,大爱。
以前对javascript某些概念迷迷糊糊,虽然知道怎么回事,但一直弄不明白其中的原因...


那么就先拿以前一直弄不明白的这道题讲讲吧,如下:

例1:

复制代码
< href ="javascript:;" >点我 </ a > /
< href ="javascript:;" >点我 </ a > /
< href ="javascript:;" >点我 </ a >
< script  type ="text/javascript" >
var  atags  =  document.getElementsByTagName( ' a ' );
for  ( var  i  =   0 , max  =  atags.length; i  <  max; i ++ ) {
    atags[i].onclick 
=   function () {
        alert(i);
    }
}
</ script >
复制代码

预期结果可能是想弹出 0,1,2。可惜的是都弹出了:3
如果你一搜,那很多结果会是叫你用闭包,如下面:

例2:

复制代码
< script  type ="text/javascript" >
var  atags  =  document.getElementsByTagName( ' a ' );
for  ( var  i  =   0 , max  =  atags.length; i  <  max; i ++ ) {
    (
function (index) {
        atags[i].onclick 
=   function () {
            alert(index);
        }
    })(i);
}
</ script >
复制代码

 

那这样真是闭包的原因吗?首先我们来了解javascript的几个知识点:

1、作用域
2、闭包
3、自执行函数。
4、值类型和引用类型

 

我来引用一下最近读这本书的几句精解:

1、JavaScript唯一能创建新作用域的地方是 function
2、包裹一些局部变量的一个函数叫做一个闭包
3、自执行函数表达式这个大家应该都很清楚了,不清楚就去看下大叔的:即调用的函数表达式
4、这个也应该清楚吧,我说下吧:Number Boolean String 在 js 里属于值类型,对像属于引用类型,如下例:

复制代码
< script  type ="text/javascript" >
function  changeValue(value) {
    value 
=   5 ;
}
function  changeObj(objValue) {
    objValue.i 
=   5 ;
}

var  i  =   0 ;
var  obj  =  { i:  0  };

changeValue(i);
changeObj(obj);

alert(i); 
// 0
alert(obj.i);  // 5
</ script >
复制代码

 

到这里,上面的几个知识点,应该都比较清楚了,现在我们来分析一下例2是不是闭包这回事。
先来看作用域:JavaScript唯一能创建新作用域的地方是 function,那么就是说像 for 这类的是不会产生自己的作用域的。我们来实验一下。

for (var i = 0; i  <  5 ; i++) {
    //这里干点啥
}
alert(i); //5

 

可以看出,for里的定义确实不会产生自己的作用域,这个其实也就是在全局里定义了一个变量i,就像以下这样:

var i = 0;
for (; i  <  5 ; i++) {
    
}
alert(i); //5

 

贴心提示:从上面的例子我们能看出,一定要理解作用域,否则很容易发生冲突。比如:

复制代码
//a某在这写了个变量 i
var i = 9527;
//b某在这写了这货
for (var i = 0; i  <  5 ; i++) {
    //
}
//a某在这果断悲剧了。
alert(i);
复制代码

 

那么我们再来看上面的例1,这时我们应该很清楚为什么会全部弹出:3了。
因为所有链接弹出的是全局变量i,而全局变量i在循环完后的值是3,如下:

复制代码
< script  type ="text/javascript" >
var  atags  =  document.getElementsByTagName( ' a ' );
for  ( var  i  =   0 , max  =  atags.length; i  <  max; i ++ ) {
    atags[i].onclick 
=   function () {
        alert(i);
    }
}
alert(i); 
// 这里显示:3
</ script >
复制代码

 

那么例2是闭包的原因吗?我们看第2个知识点:

2、包裹一些局部变量的一个函数叫做一个闭包 //显然例2不能算是闭包。

 

再说为什么例2可以达到预期呢,3、4知识点来解释。
自执行函数 和 值类型
我们在调用一个函数并传一个值类型参数时,实际是把值给传过去了。可以看第4知识点的例子。
那我们就不难理解例2的结果了。比如我们可以把那个自执行函数拿到外面:

复制代码
< script  type ="text/javascript" >
function  bind(index) {
    atags[index].onclick 
=   function () {
        alert(index);
    }
}
var  atags  =  document.getElementsByTagName( ' a ' );
for  ( var  i  =   0 , max  =  atags.length; i  <  max; i ++ ) {
    bind(i);
}
</ script >
复制代码

 

好,这篇就到这了,有什么说错的地方欢迎大家指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值