资讯专栏INFORMATION COLUMN

【转】javascript:with的用法以及延长作用域链

weapon / 1653人阅读

摘要:来看一下语句的作用通俗的说,就是引用对象,并对该对象上的属性进行操作,其作用是可以省略重复书写该对象名称,起到简化书写的作用。

原文链接:https://www.cnblogs.com/zz334...

《Javascript高级程序设计(第二版)》第66页中提到:“由于with语句的变量对象是只读的,结果url就成了函数执行环境的一部分,因而可以作为函数的值被返回。”,不知道谁看完觉得一头雾水?

第三版中75页则更是难懂:“至于with语句内部,则定义了一个url的变量,因此url就成了函数执行环境的一部分,所以可以作为函数的值被返回”

首先来看看他举的例子:

function buildUrl(){  
     var qs="?debug=true";  
     with(location){  
          var url=href+qs;  
     }  
     return url;  
}  
var result=buildUrl();  
  
alert(result);  

如果你没读过着本书,并且需要学习javascript,请思考并尝试运行该例子。
最后弹出的不是undefined,而是你的静态页地址+qs的值。

来看一下with语句的作用:

通俗的说,就是引用对象,并对该对象上的属性进行操作,其作用是可以省略重复书写该对象名称,起到简化书写的作用。

但是有几个问题需要注意:

1、with代码块中,javascript引擎对变量的处理方式是:先查找是不是该对象的属性,如果是,则停止。如果不是继续查找是不是局部变量。(在《Javascript高级程序设计(第二版)》中提到的观点,跟这一点恰好相反,但是实例可证明其是错误的,会在接下来介绍)

2、就算在with语句中使用 var 运算符重新定义变量(该变量是with引用对象的属性),如果该属性是可写属性,那么也会给对象的属性赋值。

3、如果你想通过with语句,对引用对象添加多个属性,并为每个属性赋值,这是不可能的!也就是说,要赋值的只能是对象已经存在并且可以写入的属性(不能是只读属性)。

再来看看开头提到的那句话

“由于with语句的变量对象是只读的,结果url就成了函数执行环境的一部分,因而可以作为函数的值被返回。”

反过来:如果with语句的变量对象是可写入的…… 刚才第3点提过,不能给对象写入原来不存在的属性,先这样理解,下面还有另外的含义。

那延长作用域链又是怎么回事?

一般的,“由于with语句块中作用域的‘变量对象’是只读的,所以在他本层定义的标识符,不能存储到本层,而是存储到它的上一层作用域”。这里又要理解有一层“只读”的含义。

在Javascript的作用域中(作用域,想想就是函数块,每个函数都会有个函数名,就算是匿名函数也有个空函数名),那么创建作用域的时候,本层的标识符就可以寄托在这个作用域下,而with语句块中作用域的‘变量对象’是只读的,不能存储标识符,只能存储在其上一层,这就是延长作用域链。其实,这和上面说的不能给对象添加属性有同工之处。

其实,完全可以这样理解,在Javascript中,没有块级作用域,就是说除了函数,其他的块级代码都没有自己的作用域。

现在说一下之前提到的with代码块中变量处理方式的问题

用事实说话:

var o={href:"sssss"};  
var href="1111";  
function buildUrl(){  
     var qs="?debug=true";       
     with(o){  
          href="2222";  
          var url=href+qs;  
     }      
     return url;  
}  
var result=buildUrl();  
alert(result);  //2222?debug=true
alert(href);  //1111

很明显,with语句中并没有更改变量href的值,而是更改了 o 对象的 href 属性。

就是说,with中首先查找的是相关对象的属性,如果没有,才改变变量的值。

将以上例子o对象的href属性去掉

var o={};  
var href="1111";  
function buildUrl(){  
     var qs="?debug=true";       
     with(o){  
          href="2222";  
          var url=href+qs;  
     }      
     return url;  
}  
var result=buildUrl();  
alert(result);  //2222?debug=true
alert(href); //2222

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103727.html

相关文章

  • JavaScript作用域链

    摘要:而作用域链则控制着变量与函数的可见性和生命周期。三延长作用域链在中,和关键字能延长作用域链,对来说,将会指定一个只读对象添加到作用域链中。 本文共 1200 字,读完只需 4 分钟 概述 JavaScript 中的可执行代码有其执行上下文,在执行上下文中,有三个重要的元素: 变量对象(variable object) 作用域链(scope chain) this 其中,变量对象是上...

    Karrdy 评论0 收藏0
  • Javascript执行环境和作用注意要点

    摘要:所以,全局执行环境的变量对象始终都是作用域链中的最后一个对象。搜索过程从作用域链的最前端开始,逐级向后回溯,直到找到标识符为止。查询标识符搜索过程就是沿作用域链向上查询的过程。 执行环境 执行环境就是环境,是js中最重要的概念。执行环境定义了变量或函数有权访问的其他数据。每个执行环境都有一个与之相关的变量对象(我们编写的代码无法访问这个对象)。 全局执行环境(是最外围的执行环境。在W...

    CKJOKER 评论0 收藏0
  • 【JS. ES5重点笔记】执行环境和作用

    摘要:作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。这样,一直延续到全局执行环境全局执行环境的变量对象始终都是作用域链中的最后一个对象。如果在局部环境中没有找到该变量名,则继续沿作用域链向上搜索。 【JavaScript.ES5】执行环境和作用域 参考文献: Nicholas C.Zakas 《JavaScript》高级程序设计 仅为个人学习参考文献的内容记录的笔记。存...

    Jeffrrey 评论0 收藏0
  • JavaScript基础系列---执行环境与作用域链

    摘要:延长作用域链下面两种语句可以在作用域链的前端临时增加一个变量对象以延长作用域链, 问题 今天看笔记发现自己之前记了一个关于同名标识符优先级的内容,具体是下面这样的: 形参优先级高于当前函数名,低于内部函数名 形参优先级高于arguments 形参优先级高于只声明却未赋值的局部变量,但是低于声明且赋值的局部变量 函数和变量都会声明提升,函数名和变量名同名时,函数名的优先级要高。执行代...

    J4ck_Chan 评论0 收藏0
  • JavaScript高级程序设计(第3版)》——变量、作用域和内存问题(四)

    摘要:执行环境的类型有两种全局全局执行环境局部函数执行环境每个环境都可以向上搜索作用域链,以查询变量和函数名但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。内部可通过作用域链访问外部,外部不能访问内部。 变量、作用域和内存问题 ECMAScript 数据类型 基本类型(5种): Undefined,Null,Boolean,Number,String typeof() 检测...

    YacaToy 评论0 收藏0

发表评论

0条评论

weapon

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<