关于js with语句的一些理解
今天看到js的with语句部分,书中写到,with语句接收的对象会添加到作用域链的前端并在代码执行完之后移除。看到这里,我有两点疑问,添加到作用域链前端是不是指对象会被放置到作用域链的最底部,然后查找变量时最先查找这个对象(按照我的理解,js的作用域链查找变量的过程是一个冒泡的过程,底部开始往上走,找到了就停止冒泡),第二点就是,执行之后移除是不是指with语句之后就移除那个对象。于是写了一个简单的例子来验证一下。
var b = {a:2};
function sayA(){
var a = 1;
with(b){alert(a);}
alert(a);
}
sayA();
代码运行结果是2和1。这证实了我之前的猜想,因为正常情况,位于作用域链底部的应该是函数的局部变量a,然而with语句中的a却是对象b的字段a,这证明对象b占据了作用域链中最底部的位置。而with语句之后的a的值又变成了1,说明对象b已从作用域链最底部移除。我自己认为在with语句中,这时的执行环境就是对象b,而不是函数,所以首先访问b中的a值。
我尝试在函数外直接访问a,结果当然是undefined,因为这时的执行环境应该是全局环境,而全局环境并没有这个a值,只有通过b.a才可以访问b中的a,所以可以这样说with语句其实还提供了简写访问对象字段的途径。假设b中有50个字段,你要全部访问,正常情况你要写50个b.xxx,而使用with语句只要直接写字段名就行了。
然而,我又有了一个疑问,我在with语句中创建一个变量,这个变量究竟属于谁。如果按照我的理解,这个变量应该属于对象b。
var b = {a:2};
function sayA(obj){
var a = 1;
with(b){a=5;c = 6;}
alert(c);
}
sayA();
alert(b.c);
alert(b.a);
但是, 运行结果是6、undefined和5。这说明with语句中的对象并不是作为执行环境添加到作用域链中的,仅仅是作为一个变量添加到with语句所在的执行环境之中,with语句中的变量还是属于with语句所在的执行环境(这里是函数sayA),而对b的字段的改变也会真正影响到b。
总结
- 在with语句块中,只是改变了对变量的遍历顺序,由原本的从执行环境开始变为从with语句的对象开始。当尝试在with语句块中修改变量时,会搜索with语句的对象是否有该变量,有就改变对象的值,没有就创建,但是创建的变量依然属于with语句块所在的执行环境,并不属于with对象。
- 离开with语句块后,遍历顺序就会再次变成从执行环境开始。
- 其实概括来说,和书本所总结的是一致的,with语句接收的对象会添加到作用域链的前端并在代码执行完之后移除。
本人见解,如有错误,欢迎指正。
关于js with语句的一些理解的更多相关文章
- 封装常用的js(Base.js)——【01】理解库,获取节点,连缀,
封装常用的js(Base.js)——[01]理解库,获取节点,连缀, youjobit07 2014-10-10 15:32:59 前言: 现如今有太多优秀的开源javascript库, ...
- 优化 JS 条件语句的 5 个技巧
优化 JS 条件语句的 5 个技巧 原创: 前端大全 前端大全 昨天 (给前端大全加星标,提升前端技能) 编译:伯乐在线/Mr.Dcheng http://blog.jobbole.com/11467 ...
- JS高阶函数的理解(函数作为参数传递)
JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...
- Java中关于static语句块的理解
Java中关于static语句块的理解 一.static块会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法. 实例一 public class A{ String name ...
- Js基本语句
js基本语句整理导向图 ---欢迎收藏^ - ^
- vue.js循环语句
vue.js循环语句 循环使用 v-for 指令. v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组, site 是数组元素迭代的别名. v-for 可以 ...
- JS循环语句的理解
循环语句就是让程序重复性去做某些工作 最常见的就是for循环 那它的写法都有哪些呢? 1.必须要有初始值 2.要有条件判断 3.状态的改变 4.循环体 一定要控制循环多少次结束,否则就变成了死循环,消 ...
- 对JS事件机制的深入理解
一.发生一个事件时,事件及事件处理程序会被放入浏览器的事件队列,事件可归为以下几类: 浏览器事件:window.load.document.DomContentLoaded等 网络请求事件:ajax. ...
- Js中函数式编程的理解
函数式编程的理解 函数式编程是一种编程范式,可以理解为是利用函数把运算过程封装起来,通过组合各种函数来计算结果.函数式编程与命令式编程最大的不同其实在于,函数式编程关心数据的映射,命令式编程关心解决问 ...
随机推荐
- oracle 如何恢复误删的表记录数据
--开启行移动功能 ALTER TABLE tablename ENABLE row movement ; --恢复表数据,时间为删除或修改的时间点 flashback table tablename ...
- 码农谷 球从M米高度自由下落第N次落地时反弹的高度
题目描述 一球从M米高度自由下落,每次落地后返回原高度的一半,再落下.它在第N次落地时反弹多高?共经过多少米? 保留两位小数. 输入描述 M N 输出描述 它在第N次落地时反弹多高?共经过多少米? 保 ...
- mac ping ip地址
Mac下有个类似于Windows下CMD的模式叫做终端,但是这个模式和Windows下的CMD有着很大的差别. 工具/原料 Mac电脑一台 方法/步骤 首先通过菜单栏的搜索功能找到“终端”,也可以 ...
- IIS服务器环境配置(一)
在开始-> 控制面板 ->打开或关闭功能 IIS 服务器程序 勾选 HTML勾选 完成添加后 重启 确认是否添加上在控制面板的 管理工具中查看
- c语言学习的第四天2
上图显示了float和double的精度,精度:就是指数值的精确程度,浮点类型可表示的数值范围很大,但只有几位是精确的,可以通过小 数所占的位数来获取,float小数部分最多能有7位有效数字,但绝对能 ...
- HDFS文件读写流程
一.HDFS HDFS全称是Hadoop Distributed System.HDFS是为以流的方式存取大文件而设计的.适用于几百MB,GB以及TB,并写一次读多次的场合.而对于低延时数据访问.大量 ...
- 配置visual studio code进行asp.net core rc2的开发(转载jeffreywu)
1.安装.net core sdk https://github.com/dotnet/cli#installers-and-binaries,根据你的系统选择下载 2.下载vscode的C#扩展插件 ...
- 18.python的异常处理
python中至少包括两种错误:语法错误(syntax errors)和异常(exceptions). 1.语法错误 语法错误,也被称作解析错误
- SQLserver使用映射表进行数据相关操作
基本需求: 老数据有老数据的顺序编码规则,新数据有新数据的顺序编码规则,但是老数据的编码还是要更新相应的东西,新数据也得实时更新,在新数据中已经用新编码规则对老数据对进行编码,在上报表中既要新增新数据 ...
- 微信支付开发,再次签名,APP调用
1.商户服务器生成支付订单,先调用[统一下单API]生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付. 再次生成签名的时候,按照接口: https://pay.weixin.q ...