唯品秀前端博客

很多人可能不知道这个东西,也许你知道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无用论的由来。

本站所有文章、图片、资源等如无特殊说明或标注,均为来自互联网或者站长原创,版权归原作者所有;仅作为个人学习、研究以及欣赏!如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,邮箱:343049466@qq.com
赞(2) 打赏
标签:

上一篇:

下一篇:

相关推荐

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

表情

最新评论

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

    MARK收藏。。。

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

    厉害,受教了

  3. 暂无留言哦~~
谢谢你请我吃鸡腿*^_^*

支付宝扫一扫打赏

微信扫一扫打赏