理解javascript中的with关键字

2023-12-08前端开发
30

当我们在使用JS进行开发时,可能会遇到使用with关键字的代码。with可以被用来打破常规的JS作用域规则,允许我们更方便地访问某些对象中的属性和方法。然而,with关键字在使用上很容易出错,也容易导致代码不易阅读和维护。因此,在使用with语句时,需要谨慎使用,遵循一些约定和最佳实践,下面将详细讲解“理解JavaScript中的with关键字”,帮助读者更好地理解with语句。

什么是With语句

在JavaScript中,with语句是一种让你在多次访问同一个对象的时候,可以省略对象名进行访问的方式。

一般语法如下:

with (expression) statement

例如:

var obj = {num:42};
with(obj) {
    console.log(num); // 42
}

With语句的用法

JavaScript的with语句可以让你在多次访问同一个对象的时候,可以省略对象名进行访问的方式,这无疑带来了一定的便利。 然而,使用with语句不仅会降低代码的可读性、可调试性,而且还可能造成性能上的问题,并且有安全漏洞,因此在实际应用中,我们应该尽量避免使用它。

with语句当中expression所返回的对象,会被绑定到with语句体内的一个新变量当中。我们随后就可以通过省略对象名,直接调用这个对象内的所有方法和属性了。

例如:

var obj = {num: 42};

with (obj){
    console.log(num); // 42
}

通过上面的代码,我们可以看到,with语句中的obj对象被绑定到了num变量上,并且可以直接访问到num属性。

With语句的缺点

虽然with语句可能使编码更容易,但它也有很多缺点:

  1. 可读性差:代码在使用 with语句时变得混乱。代码没有清晰地表达出操作的对象,尤其是钩子代码和回调函数,会被嵌入到 with 上下文中,使其难以确定。

  2. 性能问题:with 语句会使 JavaScript 引擎难以优化代码,从而导致程序运行缓慢。如果应用程序需要处理许多对象,那么大量使用 with 语句会增加资源消耗的可能性。

  3. 安全问题:with语句存在安全漏洞,使用with语句,就意味着你信任数值传递到with语句中的属性名称,如果传递了一个恶意对象而不是可预料的对象,攻击者可能可以定义有害行为,并可能比使用显式对象引用错误更难发现和诊断这些行为。

因此,我们不建议使用 with 语句,相反请使用显式对象引用,例如:

var obj = {num: 42};

console.log(obj.num); // 42

不要使用 With 语句的情况。

一般来说,我们不建议使用 with 语句,下面是使用 with 的情况列表:

  1. 速度

如果您的 JavaScript 程序需要处理许多对象,则大量使用 with 语句会增加资源消耗的可能性,因此会导致程序运行缓慢。

  1. 可读性

代码在使用 with 语句时变得混乱。如果您使用回调,将难以判断回调的目标对象。

  1. 安全

如果编写不可预测的代码,with 语句会导致 JavaScript 漏洞。

为了弥补 with 语句 带来的缺点,可以使用立即执行函数(Immediately Invoked Function Expressions, IIFEs),也就是JavaScript中的自执行函数:

var obj = {num: 42};

(function(obj){
    console.log(obj.num); // 42
})(obj);

在以上代码中,我们使用了自执行函数并将obj作为它的参数传递进去,这样就避免了with语句的缺点。

示例1:

  var book = {
    "name": "《JavaScript高级程序设计》",
    "author": "尼古拉斯·C.萨卡斯",
    "publishTime": "2013年3月6日",
    "price": 89.00
  };

with(book) {
    console.log("书名 = ", name);
    console.log("作者 = " , author);
    console.log("发布时间 = ",publishTime);
    console.log("价格 = ", price);
}

代码执行效果如下:

书名 = 《JavaScript高级程序设计》
作者 =  尼古拉斯·C.萨卡斯
发布时间 =  2013年3月6日
价格 =  89

示例2:

var x = 1, y = 2;

with({x: 3, y: 4}){
    console.log(x + y);  // 7
    console.log(x - y);  // -1
}

代码执行效果如下:

7
-1

因为我们在with语句中传入了一个新的对象,这个新对象属性值和原先的变量名是一样的,但是结果不一样,从这里我们可以看出,代码中的x和y示例,是有时候不一定会指向全局变量。

The End

相关推荐

layui实现图片上传成功后回显点击放大图片功能
layui实现图片上传成功后回显点击放大图片功能,html代码部分: !-- html代码--div class="layui-form-item" label class="layui-form-label"上传图片/label div class="layui-input-block" button type="button" class="layui-btn" id="license-auth-letter-...
2025-09-06 前端开发
202

Layui实现数据表格中鼠标悬停图片放大离开时恢复原图
Layui实现数据表格中鼠标悬停图片放大离开时恢复原图的效果,最终效果如下图所示: 实现代码如下,在done函数中调用hoverOpenImg方法 var tableIns = window.demoTable = table .render({ elem : '#idTest', id : 'idTest', url : '/postData', //width : 150...
2025-09-04 前端开发
112

layui点击文本输入框调起弹出选择框并选择内容的两种方法参考
我们在用到layui时候,需要点击文本输入框调起弹出选择框并选择内容,这个要怎么操作呢?以下两种方法可以参考: 1、点击名称,弹出信息弹框,选择表格中的某一行,实现效果如下: html页面代码 !--计量器具弹出层-- div id="equipment" lay-filter="equipmen...
2025-09-02 前端开发
167

网站部署https后百度地图不显示问题
https的网站如果引用百度地图,会出现加载不了的问题,这是因为涉及到跨域问题,网站是https的,但是引用百度地图的是http的,这个要怎么操作呢? 比如我引用的地址:http://api.map.baidu.com/api?v=2.0ak=AK显示 后来看了一下,少了一个s=1字段,加一下s=1...
2025-07-28 前端开发
139

微信小程序实现点击复制功能和手机拨打电话功能
做小程序项目的时候,客户提了一个功能需求优化,就是长按文字需要复制全部内容,因为有的手机支持全选复制,有的手机不支持全选复制。 通过设置系统剪贴板的内容和获取系统剪贴板的内容实现复制功能 html相关代码: van-field value="{{form.contactPhone}}"...
2025-07-02 前端开发
78

js拖拽排序插件Sortable.js如何使用
由于项目功能需要,要实现对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好的满足这个需求,而且它还是开源的,于是乎就开始学习使用Sortable.js 特点 轻量级但功能强大 移动列表项时有动画 支持触屏设备和大多数浏览器(IE9及以下除外) 支持...
2025-06-12 前端开发
161