唯品秀前端博客
当前位置: 前端开发 > JavaScript > 理解js中的作用域链增强with上下文以及变量泄露问题

很多人可能不知道这个东西,也许你知道with关键字的作用在于改变作用域但会说它无用,但不管你是否知道或者支持with无用论,如果哪天有人拿它作为一道面试题,你事先没踩过这个坑或许难倒了你,下面结合实例理解下with。

with的基本用法

1
2
3
4
5
6
7
8
var obj = {
  a: 1,
  b: 2,
  c: 3
};

// 如果想获取obj中的字段你恐怕会这样
console.log(obj.a,obj.b,obj.c)

使用with

1
2
3
with(obj){
  console.log(a,b,c)
}

面试题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var a = null;
function foo(obj) {
    with (obj) {
        a = 2;
    }
}

var o1 = {
    a: 3
};

var o2 = {
    b: 3
}

foo(o1);
console.log(o1.a);

foo(o2);
console.log(o2.a);
console.log(a);

// 答案:2 nudefined 2

分析理解

  • 首先,第一个o1传进去的是{a:3},with中obj获取到了{a:3},并且其中a再次改写成2,这时候我们输出o1.a就是2,因为对象改变是引用地址改变
  • 同样道理我们再传入o2,但o2传进去的是{b:3},with接收到了这个参数对象,重新改写a,发现这个对象没得a这个字段,然后你还要打印o2.a,结果就是undefined
  • 在这一步时候我们虽然没有改写o2下的a成功,但执行a = 2,那既然传过来的对象没有a字段,那作为直接赋值变量就给到了全局a,结果第三步直接打印a找到了2

小结

浓缩点说:实例中原本想改变的是传进来的obj,如果obj有对应的a,那就把这个a给改变 = 2,如果发现obj中没有,那它也不会自动往obj上添加,但它会直接给全局增加一个a = 2,这就是with引起的变量泄露问题,想想上面我们一开始给全局定义了一个a初始化为null,但在后期使用with过程中某次修改失败,导致改变了全局的a,想想是不是有些可怕,这恐怕就是很多人支持with无用论的由来。

「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」

分享到:
赞(1) 打赏
谢谢你请我吃鸡腿*^_^*

支付宝扫一扫打赏

微信扫一扫打赏

标签:

上一篇:

下一篇:

相关推荐

2 条评论关于"理解js中的作用域链增强with上下文以及变量泄露问题"

最新评论

  1. 谨记沵旳容颜
    Windows 10 Firefox 56.0

    MARK收藏。。。

  2. 巴山夜雨ソ涨相思
    Windows 7 Chrome 86.0.4240.198

    厉害,受教了

  3. 暂无留言哦~~

博客简介

一个关注Web前端开发技术、关注用户体验、坚持更多原创实战教程的个人网站,梦想一旦被付诸行动,就会变得神圣,愿景:成为宇宙中最具有代表性的前端技术类博客。主题开源 

精彩评论

友情链接

他们同样是一群网虫,却不是每天泡在网上游走在淘宝和网游之间、刷着本来就快要透支的信用卡。他们或许没有踏出国门一步,但同学却不局限在一国一校,而是遍及全球!申请交换友链

站点统计

  • 文章总数: 295 篇
  • 草稿数目: 0 篇
  • 分类数目: 17 个
  • 独立页面: 7 个
  • 评论总数: 1011 条
  • 链接总数: 14 个
  • 标签总数: 490 个
  • 注册用户: 2 人
  • 访问总量: 9,460,480 次
  • 最近更新: 2021年9月26日
服务热线:
 173xxxx7240

 QQ在线交流

 旺旺在线