谈谈一道js笔试题,涉及作用域链、闭包

题如下,让你写出输出结果:

function test(){
    var n=4399;
    function add(){
        n++;
        console.log(n);
    }
    return {n:n,add:add}  
    // 一个匿名变量

}
var result=test(); //  
var result2=test();//
result.add();//4400 
result.add();//4401
console.log(result.n);//4399
result2.add();4400


先说说return {n:n,add:add},可能一开始看到很懵逼,其实这就是一个匿名对象。冒号前面的n是属性名,后面的n是值。并且属性n的值n是一个number,也就是基本类型,它是不会变的,除非被重新赋值!!!但是add的值也就是add函数,是引用类型值,是会随着函数的多次调用,而改变其结果。

var result=test();这里的test()就是得到了return的{n:n,add:add},并将该值存入result的堆内存。这时的n值还是4399,为什么不是4400呢,不是有n++吗?很简单,因为add函数没有被调用过,因此n没有+1。

var result2=test();基本与上面相同,不同的是存入了不同的堆内存。因此,result和result2相互独立。

这里多说一句,如果是:var result2=result; 则result2的值不是纯粹的{n:n,add:add},而是存着指向{n:n,add:add}的指针,因此result和resut2指向同一个对象,是相互影响的。

result.add(); 调用了add函数,n++执行了,所以是4400。注意,这里的add函数是闭包,保存了自己的作用域链。add中的要用的n值是test函数中的n值,即向上追溯作用域链。

因此,这里的add函数可以等价于

function add(){
    var n=4399;
     n++;
    console.log(n);

}

result.add(); 结果4401,不解释了。

console.log(result.n) 还是4399,刚才说了,属性n存的是基本类型值,不变。


result2.add(); 因为result和result2指向两个不同的对象(虽然表达式是相同的),有不同的作用域链

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值