今天看到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语句的一些理解的更多相关文章

  1. 封装常用的js(Base.js)——【01】理解库,获取节点,连缀,

    封装常用的js(Base.js)——[01]理解库,获取节点,连缀,  youjobit07 2014-10-10 15:32:59 前言:       现如今有太多优秀的开源javascript库, ...

  2. 优化 JS 条件语句的 5 个技巧

    优化 JS 条件语句的 5 个技巧 原创: 前端大全 前端大全 昨天 (给前端大全加星标,提升前端技能) 编译:伯乐在线/Mr.Dcheng http://blog.jobbole.com/11467 ...

  3. JS高阶函数的理解(函数作为参数传递)

    JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...

  4. Java中关于static语句块的理解

    Java中关于static语句块的理解 一.static块会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法. 实例一 public class A{ String name ...

  5. Js基本语句

    js基本语句整理导向图 ---欢迎收藏^ - ^

  6. vue.js循环语句

    vue.js循环语句 循环使用 v-for 指令. v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组, site 是数组元素迭代的别名. v-for 可以 ...

  7. JS循环语句的理解

    循环语句就是让程序重复性去做某些工作 最常见的就是for循环 那它的写法都有哪些呢? 1.必须要有初始值 2.要有条件判断 3.状态的改变 4.循环体 一定要控制循环多少次结束,否则就变成了死循环,消 ...

  8. 对JS事件机制的深入理解

    一.发生一个事件时,事件及事件处理程序会被放入浏览器的事件队列,事件可归为以下几类: 浏览器事件:window.load.document.DomContentLoaded等 网络请求事件:ajax. ...

  9. Js中函数式编程的理解

    函数式编程的理解 函数式编程是一种编程范式,可以理解为是利用函数把运算过程封装起来,通过组合各种函数来计算结果.函数式编程与命令式编程最大的不同其实在于,函数式编程关心数据的映射,命令式编程关心解决问 ...

随机推荐

  1. RPC通信(Windows版、Android版)

    1.RPC通信模型 2.调用截图 服务器端 PC客户端: Android客户端: 3.remotetea jrpcgen.jar:生成Java源文件 oncrpc.jar:框架通信调用 portmap ...

  2. MySQL安装图文教程

    下载 1.下载地址: http://www.mysql.com/downloads/ 2.下载图解 下载社区版本就可以,社区版里有我们的想要的几乎全部功能.只不过 商业版的mysql会提供一定高级的解 ...

  3. js设计模式(12)---职责链模式

    0.前言 老实讲,看设计模式真得很痛苦,一则阅读过的代码太少:二则从来或者从没意识到使用过这些东西.所以我采用了看书(<js设计模式>)和阅读博客(大叔.alloyteam.聂微东)相结合 ...

  4. 设置peoplecode trace

    Configuring PeopleCode Trace Select PeopleTools, Utilities, Debug, Trace PeopleCode to access the Tr ...

  5. CSS3 column-rule-style 属性

    CSS column-rule-style属性用于在多列布局中指定列与列之间通过column rule属性设置的分隔线的样式.column-rule是列与列之间的一条垂直分隔线,你可以使用column ...

  6. DTD 知识归纳总结

    一:在xml文件中引用一个dtd规则. <!DOCTYPE 根元素 [元素声明]> 二: xml文档中中包含的内容模块 元素:元素是 XML 以及 HTML 文档的主要构建模块. 属性:属 ...

  7. Jquery权威指南

    1.Radio <input id="Radio1" name="rdoSex" type="radio" value="男 ...

  8. Learning Scrapy笔记(零) - 前言

    我已经使用了scrapy有半年之多,但是却一直都感觉没有入门,网上关于scrapy的文章简直少得可怜,而官网上的文档(http://doc.scrapy.org/en/1.0/index.html)对 ...

  9. python3.3中使用tornado.options.parse_config_file的时候,在windows下conf为utf-8时,报错的问题

    由于我的windows7下的默认编码是gbk 在调用tornado.options.parse_config_file时,内部代码为 with open(path) as f: exec_in(f.r ...

  10. C# 页面抓取类

    抓取网站页面的内容,简单的类应用,代码如下: /// <summary> /// 获取页面内容 /// </summary> /// <param name=" ...