今天看到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. javascript事件机制

    ① javascript绑定事件的方式 http://blog.iderzheng.com/dom-javascript-event-binding-comparison/ ② javascript事 ...

  2. javascript之for-in循环(for-in Loops)

    for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”. 从技术上将,你可以使用for-in循环数组(因为JavaScript中数组也是对象),但这是不推荐的.因为如果数 ...

  3. Android IOS WebRTC 音视频开发总结(十四)-- sip和xmpp异同

    这篇文章主要介绍XMPP与SIP,很多人容易混淆这两个概念,转载请说明出处(博客园RTC.Blacker). 简介:XMPP和SIP都是应用层协议,主要用于互联网上发送语音和即时通讯. SIP在RFC ...

  4. string Format转义大括号:输入字符串的格式不正确。

    String.Format("{0} world!","hello") //将输出 hello world!,没有问题,但是只要在第一个参数的任意位置加上一个大 ...

  5. 捣蛋phpwind之WindFrameWork

    一直都有关注phpwind这个开源产品,从9.0开始就好关注拉,因为官方说把之前的代码重写了一遍,融入了windFramework这个框架,代码真的挺优美的,今日在做社区的一些功能,心血来潮就参考了p ...

  6. java语言基础02

    一.Java语言基础(常量的概述和使用)(掌握) 1:什么是常量 就是在程序的执行过程中其值不发生改变的量. 2:Java中常量的分类 (1):字面值常量 (2):自定义常量(面向对象部分讲解) 3: ...

  7. ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法

    参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...

  8. redmine添加自定义属性

    使用redmine创建问题的时候,可能会发现没有我们需要的属性,这时候我们可以添加自定义的属性. 以添加满意度属性为例: 1.进入redmine管理界面,选择自定义属性 2.选择问题下面的新建自定义属 ...

  9. HTML5高防win8风格

    使用HTML5做了一个高防Win8的页面,大家看看怎么样 Java..NET.PHP.Android.iOS.HTML5,CSS3. web前端.视频资料下载网站  http://51pansou.c ...

  10. js控制div动起来

    代码: <html> <head> <title>让div动的测试</title> <script language="javascri ...